Spring技术内幕——DataSourceTransactionManager

来源:互联网 发布:微信商城开发源码下载 编辑:程序博客网 时间:2024/03/29 19:06

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();          }      }  }