Spring中使用TransactionTemplate的事务管理

先看下TransactionTemplate类的源码:


public class TransactionTemplate extends DefaultTransactionDefinition
        implements TransactionOperations, InitializingBean {


    /** Logger available to subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    //用来进行事务管理的manager
    private PlatformTransactionManager transactionManager;


    public TransactionTemplate() {
    }

    public TransactionTemplate(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
        super(transactionDefinition);
        this.transactionManager = transactionManager;
    }


    /**
     * 注入transactionManager
     */
    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }


    public PlatformTransactionManager getTransactionManager() {
        return this.transactionManager;
    }

    //如果this实例化之后,transactionManager为Null会报错
    public void afterPropertiesSet() {
        if (this.transactionManager == null) {
            throw new IllegalArgumentException("Property 'transactionManager' is required");
        }
    }


    //核心代码,入参为回调接口
    public Object execute(TransactionCallback action) throws TransactionException {
        if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
            return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
        }
        else {

            //获取transactionManager的状态
            TransactionStatus status = this.transactionManager.getTransaction(this);
            Object result = null;
            try {

                //执行具体事务的操作,但是先不提交
                result = action.doInTransaction(status);
            }
            catch (RuntimeException ex) {
                // Transactional code threw application exception -> rollback
                rollbackOnException(status, ex);
                throw ex;
            }
            catch (Error err) {
                // Transactional code threw error -> rollback
                rollbackOnException(status, err);
                throw err;
            }

            //提交事务,操作生效
            this.transactionManager.commit(status);
            return result;
        }
    }


    /**
     * 执行回滚,如果doInTransaction发生异常
     */
    private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
        logger.debug("Initiating transaction rollback on application exception", ex);
        try {
            this.transactionManager.rollback(status);
        }
        catch (TransactionSystemException ex2) {
            logger.error("Application exception overridden by rollback exception", ex);
            ex2.initApplicationException(ex);
            throw ex2;
        }
        catch (RuntimeException ex2) {
            logger.error("Application exception overridden by rollback exception", ex);
            throw ex2;
        }
        catch (Error err) {
            logger.error("Application exception overridden by rollback error", ex);
            throw err;
        }
    }


}


//事务回调接口,我们只需要将需要进行事务的操作放到doInTransaction方法中实现即可

public interface TransactionCallback {


    /**
     * Gets called by {@link TransactionTemplate#execute} within a transactional context.
     * Does not need to care about transactions itself, although it can retrieve
     * and influence the status of the current transaction via the given status
     * object, e.g. setting rollback-only.
     *
     * <p>Allows for returning a result object created within the transaction, i.e.
     * a domain object or a collection of domain objects. A RuntimeException thrown
     * by the callback is treated as application exception that enforces a rollback.
     * An exception gets propagated to the caller of the template.
     *
     * @param status associated transaction status
     * @return a result object, or <code>null</code>
     * @see TransactionTemplate#execute
     * @see CallbackPreferringPlatformTransactionManager#execute
     */
    Object doInTransaction(TransactionStatus status);


}


举个栗子:

xml配置transactionTemplate,并且注入transactionManager

<?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">

    <bean id="dbcpDatasource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/jimmyChoo"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>

    <bean id="dbcpSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="dataSource" ref="dbcpDatasource"/>
        <property name="configLocation" value="beans/ibatis/dbcp/conf/ibatis-dbcp-config.xml"/>
    </bean>

    <bean id="dbcpTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dbcpDatasource"/>
    </bean>

    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="dbcpTransactionManager"/>
    </bean>
</beans>


测试类:

public class TransactionTest extends BaseTest {
    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private DbcpUserDao dbcpUserDao;

    @Test
    public void transTest(){
        //匿名类中,实现doInTransation方法
        this.transactionTemplate.execute(new TransactionCallback() {
            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {
                dbcpUserDao.delete(9);
                dbcpUserDao.insert(getUser());
                return true;
            }
        });
    }

    private UserDO getUser(){
        UserDO userDO = new UserDO();
        userDO.setName("robert");
        userDO.setAge(29);
        userDO.setJob("teacher");
        return userDO;
    }
}





©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页