spring事务深入剖析 - JDBC DataSourceTransactionManager 分析

http://blue2048.iteye.com/blog/2176676

首先介绍下DataSourceTransactionObject这个类,它是DataSourceTransactionManager的事务句柄,用于和AbstractPlatformTransactionManager接口方法之间的交互数据传递

 下面介绍DataSourceTransactionManager各个方法,解析见注释

1.  doGetTransaction

Java代码  收藏代码
  1. //产生一个DataSourceTransactionObject对象,其中持有ConnectionHolder(从ThreadLocale中拿,可能已经存在这个对象)  
  2. protected Object doGetTransaction() {  
  3.         DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
  4.         txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  5.         ConnectionHolder conHolder =  
  6.             (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
  7.         txObject.setConnectionHolder(conHolder, false);  
  8.         return txObject;  
  9.     }  

 

 

2. isExistingTransaction

 

Java代码  收藏代码
  1. //从DataSourceTransactionObject取出ConnectionHolder对象,判断connection上是否已经开启过事务protected boolean isExistingTransaction(Object transaction) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  3.         return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());  
  4.     }  

 

3. doBegin

    a. 从DataSourceTransactionObject拿出ConnectionHolder

    b. 从ConnectionHolder拿Connection,设置事务的隔离级别,并开启事务

    c. 将ConnectionHolder绑定到当前Connection上,以被嵌套的事务获取(因为JDBC连接池是根据线程绑定Connection的,所有一次嵌套事务中,使用的是同一个Connection)

Java代码  收藏代码
  1. protected void doBegin(Object transaction, TransactionDefinition definition) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  3.         Connection con = null;  
  4.   
  5.         try {  
  6.             if (txObject.getConnectionHolder() == null ||  
  7.                     txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
  8.                 Connection newCon = this.dataSource.getConnection();  
  9.                 if (logger.isDebugEnabled()) {  
  10.                     logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");  
  11.                 }  
  12.                 txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  
  13.             }  
  14.   
  15.             txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  
  16.             con = txObject.getConnectionHolder().getConnection();  
  17.   
  18.             Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
  19.             txObject.setPreviousIsolationLevel(previousIsolationLevel);  
  20.   
  21.             // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,  
  22.             // so we don't want to do it unnecessarily (for example if we've explicitly  
  23.             // configured the connection pool to set it already).  
  24.             if (con.getAutoCommit()) {  
  25.                 txObject.setMustRestoreAutoCommit(true);  
  26.                 if (logger.isDebugEnabled()) {  
  27.                     logger.debug("Switching JDBC Connection [" + con + "] to manual commit");  
  28.                 }  
  29.                 con.setAutoCommit(false);  
  30.             }  
  31.             txObject.getConnectionHolder().setTransactionActive(true);  
  32.   
  33.             int timeout = determineTimeout(definition);  
  34.             if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
  35.                 txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  
  36.             }  
  37.   
  38.             // Bind the session holder to the thread.  
  39.             if (txObject.isNewConnectionHolder()) {  
  40.                 TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());  
  41.             }  
  42.         }  
  43.   
  44.         catch (Exception ex) {  
  45.             DataSourceUtils.releaseConnection(con, this.dataSource);  
  46.             throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);  
  47.         }  
  48.     }  

 

 

4. doSuspend 

 

Java代码  收藏代码
  1. //清除DataSourceTransactionObject和ThreadLocal中存储的ConnectionHolder对象,外部保存ConnectionHolder对象,以备恢复使用  
  2. protected Object doSuspend(Object transaction) {  
  3.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  4.         txObject.setConnectionHolder(null);  
  5.         ConnectionHolder conHolder = (ConnectionHolder)  
  6.                 TransactionSynchronizationManager.unbindResource(this.dataSource);  
  7.         return conHolder;  
  8.     }  
 
5. doResume
Java代码  收藏代码
  1. //外部传入ConnectionHolder对象,恢复到ThreadLocal中去     
  2. protected void doResume(Object transaction, Object suspendedResources) {  
  3.         ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;  
  4.         TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);  
  5.     }  
 
6. doCommit
Java代码  收藏代码
  1. protected void doCommit(DefaultTransactionStatus status) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  3.         Connection con = txObject.getConnectionHolder().getConnection();  
  4.         if (status.isDebug()) {  
  5.             logger.debug("Committing JDBC transaction on Connection [" + con + "]");  
  6.         }  
  7.         try {  
  8.             con.commit();  
  9.         }  
  10.         catch (SQLException ex) {  
  11.             throw new TransactionSystemException("Could not commit JDBC transaction", ex);  
  12.         }  
  13.     }  
 
7. doRollback
Java代码  收藏代码
  1. protected void doRollback(DefaultTransactionStatus status) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  3.         Connection con = txObject.getConnectionHolder().getConnection();  
  4.         if (status.isDebug()) {  
  5.             logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");  
  6.         }  
  7.         try {  
  8.             con.rollback();  
  9.         }  
  10.         catch (SQLException ex) {  
  11.             throw new TransactionSystemException("Could not roll back JDBC transaction", ex);  
  12.         }  
  13.     }  
 
8. doSetRollbackOnly
Java代码  收藏代码
  1. protected void doSetRollbackOnly(DefaultTransactionStatus status) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  3.         if (status.isDebug()) {  
  4.             logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +  
  5.                     "] rollback-only");  
  6.         }  
  7.         txObject.setRollbackOnly();  
  8.     }  
 
9. doCleanupAfterCompletion
    a. 从ThreadLocal中将ConnectionHolder清除
    b. 回复Connecton之前的AutoCommit和IsolationLevel属性
    c. 释放connection
    d. 清除ConnectHolder相应的对象属性
Java代码  收藏代码
  1. protected void doCleanupAfterCompletion(Object transaction) {  
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  3.   
  4.         // Remove the connection holder from the thread, if exposed.  
  5.         if (txObject.isNewConnectionHolder()) {  
  6.             TransactionSynchronizationManager.unbindResource(this.dataSource);  
  7.         }  
  8.   
  9.         // Reset connection.  
  10.         Connection con = txObject.getConnectionHolder().getConnection();  
  11.         try {  
  12.             if (txObject.isMustRestoreAutoCommit()) {  
  13.                 con.setAutoCommit(true);  
  14.             }  
  15.             DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());  
  16.         }  
  17.         catch (Throwable ex) {  
  18.             logger.debug("Could not reset JDBC Connection after transaction", ex);  
  19.         }  
  20.   
  21.         if (txObject.isNewConnectionHolder()) {  
  22.             if (logger.isDebugEnabled()) {  
  23.                 logger.debug("Releasing JDBC Connection [" + con + "] after transaction");  
  24.             }  
  25.             DataSourceUtils.releaseConnection(con, this.dataSource);  
  26.         }  
  27.   
  28.         txObject.getConnectionHolder().clear();  
  29.     }  
posted @ 2018-05-17 19:46  He_quotes  阅读(2187)  评论(0)    收藏  举报