Spring中使用TransactionTemplate的事务管理

来源:互联网 发布:单片机自动门源程序 编辑:程序博客网 时间:2024/05/14 05:30

先看下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;    }}





原创粉丝点击