Spring 学习(二十六)——使用XML文件的方式配置事务

package com.hzyc.spring.jdbc.transaction.xml;

/**
 * @author xuehj2016
 * @Title: BookShopDao
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 20:32
 */
public interface BookShopDao {
    /**
     * 根据书号获取书的单价
     */
    public int getBookPriceById(String id);

    /**
     * 更新书的库存,使书号对应的库存 - 1
     */
    public void updateBookStock(String id);

    /**
     * 更新用户的账户余额 : 使 username 的 balance - price
     */
    public void updateUserAccount(String username, int price);
}
package com.hzyc.spring.jdbc.transaction.xml;

import org.springframework.jdbc.core.JdbcTemplate;

/**
 * @author xuehj2016
 * @Title: BookShopDaoImpl
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 20:39
 */
public class BookShopDaoImpl implements BookShopDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 根据书号获取书的单价
     *
     * @param id
     */
    @Override
    public int getBookPriceById(String id) {
        String sql = "select price from book where id = ?";
        return jdbcTemplate.queryForObject(sql, Integer.class, id);
    }

    /**
     * 更新书的库存,使书号对应的库存 - 1
     *
     * @param id
     */
    @Override
    public void updateBookStock(String id) {
        //检查书的库存是否足够,若不够,则抛出异常
        String stockSql = "select stock from book_stock where id =?";
        int stock = jdbcTemplate.queryForObject(stockSql, Integer.class, id);
        if (stock == 0) {
            throw new BookStockException("库存不足!");
        }

        String sql = "update book_stock set stock = stock - 1 where id =?";
        jdbcTemplate.update(sql, id);
    }

    /**
     * 更新用户的账户余额 : 使 username 的 balance - price
     *
     * @param username
     * @param price
     */
    @Override
    public void updateUserAccount(String username, int price) {
        //因为 MySQL 不支持检查约束
        //验证用户的余额是否足够,若不够,则抛出异常
        String balanceSql = "select balance from account where username =?";
        int balance = jdbcTemplate.queryForObject(balanceSql, Integer.class, username);
        if (balance < price) {
            throw new UserAccountException("余额不足!");
        }

        String sql = "update account set balance = balance - ? where username =?";
        jdbcTemplate.update(sql, price, username);
    }
}
package com.hzyc.spring.jdbc.transaction.xml;

/**
 * @author xuehj2016
 * @Title: BookShopService
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 21:22
 */
public interface BookShopService {

    public void purchase(String username, String id);

}
package com.hzyc.spring.jdbc.transaction.xml;

/**
 * @author xuehj2016
 * @Title: BookShopServiceImpl
 * @ProjectName Spring-3
 * @Description: TODO
 * @date 2018/12/21 21:24
 */
public class BookShopServiceImpl implements BookShopService {

    private BookShopDao bookShopDao;

    public void setBookShopDao(BookShopDao bookShopDao) {
        this.bookShopDao = bookShopDao;
    }

    @Override
    public void purchase(String username, String id) {

        //1.获取书的单价
        int price = bookShopDao.getBookPriceById(id);

        //2.更新书的库存
        bookShopDao.updateBookStock(id);

        //3.更新用户余额
        bookShopDao.updateUserAccount(username, price);
    }
}
package com.hzyc.spring.jdbc.transaction.xml;

/**
 * @author xuehj2016
 * @Title: BookStockException
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 21:10
 */
public class BookStockException extends RuntimeException {

    public BookStockException() {
    }

    public BookStockException(String message) {
        super(message);
    }

    public BookStockException(String message, Throwable cause) {
        super(message, cause);
    }

    public BookStockException(Throwable cause) {
        super(cause);
    }

    public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
package com.hzyc.spring.jdbc.transaction.xml;

import java.util.List;

/**
 * @author xuehj2016
 * @Title: Cashier
 * @ProjectName Spring-3
 * @Description: TODO
 * @date 2018/12/21 23:23
 */
public interface Cashier {

    public void checkout(String username, List<String> ids);
}
package com.hzyc.spring.jdbc.transaction.xml;

import java.util.List;

/**
 * @author xuehj2016
 * @Title: CashierImpl
 * @ProjectName Spring-3
 * @Description: TODO
 * @date 2018/12/21 23:24
 */
public class CashierImpl implements Cashier {

    private BookShopService bookShopService;

    public void setBookShopService(BookShopService bookShopService) {
        this.bookShopService = bookShopService;
    }

    /**
     *
     * @param username
     * @param ids
     */
    @Override
    public void checkout(String username, List<String> ids) {

        for (String id : ids) {
            bookShopService.purchase(username, id);
        }
    }
}
package com.hzyc.spring.jdbc.transaction.xml;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;

/**
 * @author xuehj2016
 * @Title: SpringTransactionTest
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 20:52
 */
public class SpringTransactionTest {
    private BookShopDao bookShopDao;
    private BookShopService bookShopService;
    private Cashier cashier;

    {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context-tx-xml.xml");
        bookShopDao = (BookShopDao) applicationContext.getBean("bookShopDao2");
        bookShopService = (BookShopService) applicationContext.getBean("bookShopService2");
        cashier = (Cashier) applicationContext.getBean("cashier2");
    }

    @Test
    public void testBookShopGetBookPriceById() {
        System.out.println(bookShopDao.getBookPriceById("1001"));
    }

    @Test
    public void testBookShopUpdateBookStock() {
        bookShopDao.updateBookStock("1001");
    }

    @Test
    public void testBookShopUpdateUserAccount() {
        bookShopDao.updateUserAccount("xuehj", 50);
    }

    @Test
    public void testBookShopService() {
        bookShopService.purchase("xuehj", "1001");
    }

    @Test
    public void testTransactionalPropagation() {
        cashier.checkout("xuehj", Arrays.asList("1001", "1002"));
    }
}
package com.hzyc.spring.jdbc.transaction.xml;

/**
 * @author xuehj2016
 * @Title: UserAccountException
 * @ProjectName Spring
 * @Description: TODO
 * @date 2018/12/21 21:16
 */
public class UserAccountException extends RuntimeException {

    public UserAccountException() {
    }

    public UserAccountException(String message) {
        super(message);
    }

    public UserAccountException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserAccountException(Throwable cause) {
        super(cause);
    }

    public UserAccountException(String message, Throwable cause, boolean enableSuppression, boolean
            writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

application-context-tx-xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context
	   http://www.springframework.org/schema/context/spring-context-4.0.xsd
	   http://www.springframework.org/schema/tx
	   http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.hzyc.spring"/>

    <!--导入资源文件-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置 c3p0 数据源-->
    <bean id="dataSource"
          class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"/>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
    </bean>

    <!--配置 Spring 的 Jdbc Template-->
    <bean id="jdbcTemplate"
          class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置bean-->
    <bean id="bookShopDao2" class="com.hzyc.spring.jdbc.transaction.xml.BookShopDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <bean id="bookShopService2" class="com.hzyc.spring.jdbc.transaction.xml.BookShopServiceImpl">
        <property name="bookShopDao" ref="bookShopDao2"/>
    </bean>

    <bean id="cashier2" class="com.hzyc.spring.jdbc.transaction.xml.CashierImpl">
        <property name="bookShopService" ref="bookShopService2"/>
    </bean>

    <!--1.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--3.配置事务属性-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!--3.配置事务切入点,以及把事务切入点和事务属性关联起来-->
    <aop:config>
        <aop:pointcut id="txPointCut"
                      expression="execution(* com.hzyc.spring.jdbc.transaction.xml.BookShopService.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
</beans>

把上述文件移动包

2、目录结构

Spring
|——src
|——|——com.hzyc.spring.jdbc.transaction.xml
|——|——|——bookshopDao.java
|——|——|——bookshopDaoImpl.java
|——|——|——bookstockException.java
|——|——|——SpringTransactionTest.java
|——|——com.hzyc.spring.jdbc.transaction.xml.service
|——|——|——BookShopService.java
|——|——|——Cashier.java
|——|——com.hzyc.spring.jdbc.transaction.xml.service.impl
|——|——|——BookShopServiceImpl.java
|——|——|——CashierImpl.java
|——|——application-context.xml
|——|——db.properties

变得文件只是application-context-tx-xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context
	   http://www.springframework.org/schema/context/spring-context-4.0.xsd
	   http://www.springframework.org/schema/tx
	   http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.hzyc.spring"/>

    <!--导入资源文件-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置 c3p0 数据源-->
    <bean id="dataSource"
          class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"/>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
    </bean>

    <!--配置 Spring 的 Jdbc Template-->
    <bean id="jdbcTemplate"
          class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置bean-->
    <bean id="bookShopDao2" class="com.hzyc.spring.jdbc.transaction.xml.BookShopDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <bean id="bookShopService2" class="com.hzyc.spring.jdbc.transaction.xml.service.impl.BookShopServiceImpl">
        <property name="bookShopDao" ref="bookShopDao2"/>
    </bean>

    <bean id="cashier2" class="com.hzyc.spring.jdbc.transaction.xml.service.impl.CashierImpl">
        <property name="bookShopService" ref="bookShopService2"/>
    </bean>

    <!--1.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--3.配置事务属性-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--根据方法名配置事务的属性-->
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="purchase" propagation="REQUIRES_NEW"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!--3.配置事务切入点,以及把事务切入点和事务属性关联起来-->
    <aop:config>
        <aop:pointcut id="txPointCut"
                      expression="execution(* com.hzyc.spring.jdbc.transaction.xml.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
</beans>

猜你喜欢

转载自blog.csdn.net/weixin_41577923/article/details/85207421
今日推荐