TZ_05_Spring_转账事务基于xml的开发

事务:通过接口的动态代理加强AccountService 实现转账的事务

ApplicationContext.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置代理的service -->
    <bean id="proxyAccountService" factory-bean="beanFactory" factory-method="getAccountService"></bean>

    <!--配置beanfactory-->
    <bean id="beanFactory" class="com.hdh.factory.BeanFactory">
        <!-- 注入service -->
        <property name="as" ref="accountService"></property>
        <!-- 注入事务管理器 -->
        <property name="tm" ref="txManager"></property>
    </bean>
    
    <!--配置service -->
    <bean id="accountService" class="com.hdh.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    <!--配置dao -->
    <bean id="accountDao" class="com.hdh.dao.impl.AccountDaoImpl">
        <!-- 注入QueryRunner -->
        <property name="runner" ref="runner"></property>
        <!-- 注入ConnectionUtils -->
        <property name="connectionUtils" ref="connectionUtils"></property>
    </bean>


    <!--配置QueryRunner -->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner"
        scope="prototype"></bean>

    <!-- 配置Connection的工具类 ConnectionUtils -->
    <bean id="connectionUtils" class="com.hdh.utils.ConnectionUtils">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>


    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--连接数据库的必备信息 -->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property>
        <property name="user" value="root"></property>
        <property name="password" value="12345"></property>
    </bean>

    <!-- 配置事务管理器-->
    <bean id="txManager" class="com.hdh.utils.TransactionManager">
        <!-- 注入ConnectionUtils -->
        <property name="connectionUtils" ref="connectionUtils"></property>
    </bean>

</beans>

2.ConnectionUtils.java  //获取当前线程上的连接

/**
 * 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定
 */
public class ConnectionUtils {

    private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 获取当前线程上的连接
     * @return
     */
    public Connection getThreadConnection() {
        try{
            //1.先从ThreadLocal上获取
            Connection conn = tl.get();
            //2.判断当前线程上是否有连接
            if (conn == null) {
                //3.从数据源中获取一个连接,并且存入ThreadLocal中
                conn = dataSource.getConnection();
                tl.set(conn);
            }
            //4.返回当前线程上的连接
            return conn;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 把连接和线程解绑
     */
    public void removeConnection(){
        tl.remove();
    }
}

3.TranscationManager.java

/**
 * 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
 */
public class TransactionManager {

    private ConnectionUtils connectionUtils;

    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }

    /**
     * 开启事务
     */
    public  void beginTransaction(){
        try {
            connectionUtils.getThreadConnection().setAutoCommit(false);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 提交事务
     */
    public  void commit(){
        try {
            connectionUtils.getThreadConnection().commit();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务
     */
    public  void rollback(){
        try {
            connectionUtils.getThreadConnection().rollback();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 释放连接
     */
    public  void release(){
        try {
            connectionUtils.getThreadConnection().close();//还回连接池中
            connectionUtils.removeConnection();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

4.接口的动态代理加强AccountService

/**
 * 用于创建Service的代理对象的工厂
 */
public class BeanFactory {

    private AccountService as;
    private TransactionManager tm;

    public void setAs(AccountService as) {
        this.as = as;
    }

    public void setTm(TransactionManager tm) {
        this.tm = tm;
    }

    public AccountService getAccountService() {

        return (AccountService) Proxy.newProxyInstance(as.getClass().getClassLoader(), as.getClass().getInterfaces(),
                new InvocationHandler() {

                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object invoke=null;
                        try {
                            // 开启事物
                            tm.beginTransaction();
                             invoke = method.invoke(as, args);
                            //事务提交
                            tm.commit();
                        } catch (Exception e) {
                            // 事物回滚
                            tm.rollback();
                        } finally {
                            // 释放连接
                            tm.release();
                        }
                        return invoke;
                    }
                });

    }
}
扫描二维码关注公众号,回复: 7018936 查看本文章

猜你喜欢

转载自www.cnblogs.com/asndxj/p/11349748.html