Spring技术内幕——DataSourceTransactionManager

Spring的事务处理中,通用的事务处理流程框架是由抽象事务管理器AbstractPlatformTransactionManager来提供的,而具体的底层事务处理实现,由PlatformTransactionManager的具体实现类来实现,如 DataSourceTransactionManager 、JtaTransactionManager和 HibernateTransactionManager等。

对于具体的事务管理器而言,它们只需要处理和具体数据源相关的组件设置就可以了。如doGetTransaction(),doCommit(status)方法等。


本文主要介绍DataSourceTransactionManager中的具体实现。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager  
        implements ResourceTransactionManager, InitializingBean {  
    //注入数据源  
    private DataSource dataSource;  
//数据源事务处理器默认构造方法,创建一个数据源事务处理器实例,并设置允许嵌套事务  
    public DataSourceTransactionManager() {  
        setNestedTransactionAllowed(true);  
    }  
    //根据给定数据源,创建一个数据源事务处理器实例  
    public DataSourceTransactionManager(DataSource dataSource) {  
        this();  
        setDataSource(dataSource);  
        afterPropertiesSet();  
    }  
    //设置数据源  
    public void setDataSource(DataSource dataSource) {  
        if (dataSource instanceof TransactionAwareDataSourceProxy) {  
            //如果数据源是一个事务包装数据源代理,则获取事务包装代理的目标数据源   
            this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource();  
        }  
        else {  
            this.dataSource = dataSource;  
        }  
    }  
    //获取数据源  
    public DataSource getDataSource() {  
        return this.dataSource;  
    }  
    //数据源事务处理器对象构造方法的回调函数  
    public void afterPropertiesSet() {  
        if (getDataSource() == null) {  
            throw new IllegalArgumentException("Property 'dataSource' is required");  
        }  
    }  
public Object getResourceFactory() {  
        return getDataSource();  
    }  
//创建事务,对数据库而言,是由Connection来完成事务工作的。该方法把数据库的//Connection对象放到一个ConnectionHolder对象中,然后封装到一个  
//DataSourceTransactionObject对象中  
    protected Object doGetTransaction() {  
        //创建数据源事务对象  
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
        //设置数据源事务对象对嵌套事务使用保存点  
        txObject.setSavepointAllowed(isNestedTransactionAllowed());  
        //从事务管理容器中获取存放数据库Connection的对象  
        ConnectionHolder conHolder =  
            (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
        txObject.setConnectionHolder(conHolder, false);  
        return txObject;  
    }  
    //判断是否已经存在事务  
    protected boolean isExistingTransaction(Object transaction) {  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
    //根据存放数据库连接的ConnectionHolder的isTransactionActive属性来判断  
        return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());  
    }  
    //处理事务开始的方法  
    protected void doBegin(Object transaction, TransactionDefinition definition) {  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
        Connection con = null;  
        try {  
            //如果数据源事务对象的ConnectionHolder为null或者是事务同步的  
            if (txObject.getConnectionHolder() == null ||  
        txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
                //获取当前数据源的数据库连接  
                Connection newCon = this.dataSource.getConnection();  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");  
                }  
                //为数据源事务对象设置ConnectionHolder  
                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  
            }  
    //设置数据源事务对象的事务同步    txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  
            //获取数据源事务对象的数据库连接  
            con = txObject.getConnectionHolder().getConnection();  
            //根据数据连接和事务属性,获取数据库连接的事务隔离级别  
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
    //为数据源事务对象设置事务隔离级别  
    txObject.setPreviousIsolationLevel(previousIsolationLevel);  
            //如果数据库连接设置了自动事务提交属性,则关闭自动提交  
            if (con.getAutoCommit()) {  
                //保存数据库连接设置的自动连接到数据源事务对象中  
                txObject.setMustRestoreAutoCommit(true);  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Switching JDBC Connection [" + con + "] to manual commit");  
                }  
                //设置数据库连接自动事务提交属性为false,即禁止自动事务提交  
                con.setAutoCommit(false);  
            }  
            //激活当前数据源事务对象的事务配置  
            txObject.getConnectionHolder().setTransactionActive(true);  
            //获取事务配置的超时时长  
int timeout = determineTimeout(definition);  
//如果事务配置的超时时长不等于事务的默认超时时长  
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
        //数据源事务对象设置超时时长  
        txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  
            }  
            //把当前数据库Connection和线程绑定  
            if (txObject.isNewConnectionHolder()) {  
        TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());  
            }  
        }  
        catch (Exception ex) {  
            DataSourceUtils.releaseConnection(con, this.dataSource);  
            throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);  
        }  
    }  
    //事务挂起  
    protected Object doSuspend(Object transaction) {  
        //获取事务对象  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
        //将事务对象中的ConnectionHolders设置为null  
        txObject.setConnectionHolder(null);  
        ConnectionHolder conHolder = (ConnectionHolder)  
        //解除事务对象和当前线程的绑定    TransactionSynchronizationManager.unbindResource(this.dataSource);  
        return conHolder;  
    }  
    //事务恢复  
    protected void doResume(Object transaction, Object suspendedResources) {  
        //获取已暂停事务的ConnectionHolder  
        ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;  
        //重新将事务对象和当前线程绑定  
        TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);  
    }  
    //事务提交  
    protected void doCommit(DefaultTransactionStatus status) {  
        //获取事务对象  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
        //通过事务对象获取数据库连接  
        Connection con = txObject.getConnectionHolder().getConnection();  
        if (status.isDebug()) {  
            logger.debug("Committing JDBC transaction on Connection [" + con + "]");  
        }  
        try {  
            //使用数据库连接手动进行事务提交  
            con.commit();  
        }  
        catch (SQLException ex) {  
            throw new TransactionSystemException("Could not commit JDBC transaction", ex);  
        }  
    }  
    //事务回滚  
    protected void doRollback(DefaultTransactionStatus status) {  
        //获取事务对象  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
        //通过事务对象获取数据库连接  
        Connection con = txObject.getConnectionHolder().getConnection();  
        if (status.isDebug()) {  
            logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");  
        }  
        try {  
            //通过调用数据库连接的回滚方法完成事务回滚操作  
            con.rollback();  
        }  
        catch (SQLException ex) {  
            throw new TransactionSystemException("Could not roll back JDBC transaction", ex);  
        }  
    }  
    //设置回滚  
    protected void doSetRollbackOnly(DefaultTransactionStatus status) {  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
        if (status.isDebug()) {  
            logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +  
                    "] rollback-only");  
        }  
        txObject.setRollbackOnly();  
    }  
    //操作完成之后清除操作  
    protected void doCleanupAfterCompletion(Object transaction) {  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
        //移除当前线程绑定的ConnectionHolder  
        if (txObject.isNewConnectionHolder()) {  
    TransactionSynchronizationManager.unbindResource(this.dataSource);  
        }  
        Connection con = txObject.getConnectionHolder().getConnection();  
        try {  
        //如果事务对象保存了自动事务提交属性,则设置数据库连接的自动事务提交属性  
            if (txObject.isMustRestoreAutoCommit()) {  
                con.setAutoCommit(true);  
            }  
            //事务结束后重置数据库连接  
            DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());  
        }  
        catch (Throwable ex) {  
            logger.debug("Could not reset JDBC Connection after transaction", ex);  
        }  
        //如果事务对象中有新的ConnectionHolder   
        if (txObject.isNewConnectionHolder()) {  
            if (logger.isDebugEnabled()) {  
                logger.debug("Releasing JDBC Connection [" + con + "] after transaction");  
            }  
            //释放数据库连接  
            DataSourceUtils.releaseConnection(con, this.dataSource);  
        }  
        //清除事务对象的ConnectionHolder  
        txObject.getConnectionHolder().clear();  
    }  
//数据源事务对象,内部类  
    private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {  
        //是否有新的ConnectionHolder  
        private boolean newConnectionHolder;  
        //是否保存自动提交  
        private boolean mustRestoreAutoCommit;  
        //设置ConnectionHolder  
        public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {  
            //为父类JdbcTransactionObjectSupport设置ConnectionHolder  
            super.setConnectionHolder(connectionHolder);  
            this.newConnectionHolder = newConnectionHolder;  
        }  
        public boolean isNewConnectionHolder() {  
            return this.newConnectionHolder;  
        }  
        //调用父类JdbcTransactionObjectSupport的相关方法,查询收费存在事务  
        public boolean hasTransaction() {  
            return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive());  
        }  
        //设置是否保存自动提交  
        public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {  
            this.mustRestoreAutoCommit = mustRestoreAutoCommit;  
        }  
        public boolean isMustRestoreAutoCommit() {  
            return this.mustRestoreAutoCommit;  
        }  
        //设置数据库连接在操作失败是,是否只回滚处理  
        public void setRollbackOnly() {  
            getConnectionHolder().setRollbackOnly();  
        }  
        public boolean isRollbackOnly() {  
            return getConnectionHolder().isRollbackOnly();  
        }  
    }  
}  



  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值