1.Spring的事務處理中,通用的事務處理流程框架是由抽象事務管理器AbstractPlatformTransactionManager來提供的,而具體的底層事務處理實現,由PlatformTransactionManager的具體實現類來實現,如 DataSourceTransactionManager 、JtaTransactionManager和 HibernateTransactionManager等。咱們以Spring中最經常使用的DataSourceTransactionManager和 HibernateTransactionManager爲例,來分析具體事務處理器的底層實現事務建立、提交和回滾的處理操做。數據庫
2.AbstractPlatformTransactionManager抽象事物處理器:session
上一篇博客中,咱們已經分析了抽象事物管理器AbstractPlatformTransactionManager的源碼,瞭解它實現了PlatformTransactionManager平臺事務管理器接口,提供了一系列設計好的事務模板方法,如事務提交、回滾等,這些模板方法的具體實現由具體的事務處理器來提供。框架
3.DataSourceTransactionManager事務處理器的實現:less
DataSourceTransactionManager數據源事務處理器是針對JDBC鏈接提供的事務處理器實現,即數據源事務處理器把數據庫Connection鏈接和當前線程進行綁定,經過直接調用數據庫鏈接Connection的提交和回滾方法實現事務的提供和回滾處理。其源碼以下:函數
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(); } } }
經過上述對數據源事務處理器的源碼分析,咱們看到,事務的提交、回滾等操做是經過直接調用數據庫鏈接Connection的提交和回滾方法實現的,因爲自動事務提交對應用程序性能影響很大,所以在進行事務提交時,咱們首先禁止數據庫鏈接的自動事務提交,事務提供操做經過手動實現。源碼分析
4.HibernateTransactionManager事務處理器的實現:性能
相對於數據源的事務處理器來講,Hibernate的事務處理器相對要複雜一些,它是經過對Hibernate的會話Session的管理來完成事務處理實現的。Hibernate事務處理器的事務處理相關源碼以下:ui
public class HibernateTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, BeanFactoryAware, InitializingBean { …… //獲取Hibernate事務 protected Object doGetTransaction() { //建立Hibernate事務對象 HibernateTransactionObject txObject = new HibernateTransactionObject(); //根據是否容許嵌套事務設置事務對象是否容許保存點 txObject.setSavepointAllowed(isNestedTransactionAllowed()); //從線程中獲取SessionHolder,SessionHolder是在事務開始時與線程綁定的。 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); //若是獲取到的SessionHolder不爲null if (sessionHolder != null) { if (logger.isDebugEnabled()) { logger.debug("Found thread-bound Session [" + SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction"); } //把獲取到的SessionHolder設置到Hibernate事務對象中 txObject.setSessionHolder(sessionHolder); } //若是當前Hibernate事務處理器有被管理的Hibernate Session else if (this.hibernateManagedSession) { try { //獲取當前的Hibernate Session Session session = getSessionFactory().getCurrentSession(); if (logger.isDebugEnabled()) { logger.debug("Found Hibernate-managed Session [" + SessionFactoryUtils.toString(session) + "] for Spring-managed transaction"); } //設置Hibernate事務對象已經存在指定的Session txObject.setExistingSession(session); } catch (HibernateException ex) { throw new DataAccessResourceFailureException( "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex); } } //若是獲取到的數據源不爲null if (getDataSource() != null) { //將獲取到的數據源和當前線程綁定 ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); } return txObject; } //是否已存在事務 protected boolean isExistingTransaction(Object transaction) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; //根據事務對象是否存在Spring管理的事務,或者經過判斷是否存在有被管理的Hibernate Session或者事務對象中有被Hibernate管理的事務 return (txObject.hasSpringManagedTransaction() || (this.hibernateManagedSession && txObject.hasHibernateManagedTransaction())); } //處理事務開始 protected void doBegin(Object transaction, TransactionDefinition definition) { //獲取事務對象 HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; //若是事務對象有ConnectionHolder,且事務對象的數據庫鏈接不是事務同步的 if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { throw new IllegalTransactionStateException( "Pre-bound JDBC Connection found! HibernateTransactionManager does not support " + "running within DataSourceTransactionManager if told to manage the DataSource itself. " + "It is recommended to use a single HibernateTransactionManager for all transactions " + "on a single DataSource, no matter whether Hibernate or JDBC access."); } Session session = null; try { //若是事務對象的SessionHolder爲null,或者事務對象Hibernate //Session是事務同步的 if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { //獲取Hibernate事務處理器中的實體攔截器 Interceptor entityInterceptor = getEntityInterceptor(); //獲取Hibernate Session,若是實體攔截器不爲null,則打開指定 //實體攔截器的Session,若是實體攔截器爲null,則打開新Session Session newSession = (entityInterceptor != null ? getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession()); if (logger.isDebugEnabled()) { logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) + "] for Hibernate transaction"); } //將獲取的Hibernate Session設置到事務對象中 txObject.setSession(newSession); } //若是Hibernate事務處理器中的SessionHolder不爲null,則 //獲取SessionHolder中已有的Hibernate Session session = txObject.getSessionHolder().getSession(); //容許爲JDBC鏈接改變事務設置 if (this.prepareConnection && isSameConnectionForEntireSession(session)) { if (logger.isDebugEnabled()) { logger.debug( "Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]"); } //獲取Session鏈接 Connection con = session.connection(); //獲取事務的隔離級別 Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); //設置事務對象的事務隔離級別 txObject.setPreviousIsolationLevel(previousIsolationLevel); } //不容許爲JDBC鏈接改爲事務設置 else { //若是事務隔離級別不是默認事務隔離級別 if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { throw new InvalidIsolationLevelException( "HibernateTransactionManager is not allowed to support custom isolation levels: " + "make sure that its 'prepareConnection' flag is on (the default) and that the " + "Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default). " + "Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " + "Hibernate properties should *not* include a 'hibernate.transaction.factory_class' property!"); } if (logger.isDebugEnabled()) { logger.debug( "Not preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]"); } } //若是事務是隻讀,且事務對象是新的Hibernate Session if (definition.isReadOnly() && txObject.isNewSession()) { //設置Hibernate Session刷新模式爲手動 session.setFlushMode(FlushMode.MANUAL); } //若是事務是非只讀的,且事務對象不是新Hibernate Session if (!definition.isReadOnly() && !txObject.isNewSession()) { //或者Hibernate的刷新模式 FlushMode flushMode = session.getFlushMode(); //設置Session的刷新模式 if (flushMode.lessThan(FlushMode.COMMIT)) { session.setFlushMode(FlushMode.AUTO); //爲事務對象設置刷新模式 txObject.getSessionHolder().setPreviousFlushMode(flushMode); } } Transaction hibTx; //獲取事務超時時長 int timeout = determineTimeout(definition); //若是事務配置的超時時長不是事務默認超時時長 if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { //獲取Hibernate Session事務 hibTx = session.getTransaction(); //爲事務對象設置超時時長 hibTx.setTimeout(timeout); //開啓事務 hibTx.begin(); } //若是事務配置的超時時長是默認超時時長 else { //經過Hibernate Session直接開啓事務 hibTx = session.beginTransaction(); } //把事務設置到事務對象的SessionHolder中,而且線程綁定 txObject.getSessionHolder().setTransaction(hibTx); //若是數據源不爲null,即設置了數據源 if (getDataSource() != null) { //使用Hibernate Session打開數據庫鏈接 Connection con = session.connection(); //建立ConnectionHolder ConnectionHolder conHolder = new ConnectionHolder(con); //設置超時時長 if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { conHolder.setTimeoutInSeconds(timeout); } if (logger.isDebugEnabled()) { logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]"); } //將數據源和JDBC ConnectionHolder綁定到當前線程 TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); //將建立的JDBC ConnectionHolder設置到事務對象中 txObject.setConnectionHolder(conHolder); } //若是事務對象中的SessionHolder是新的 if (txObject.isNewSessionHolder()) { //當SessionHolder和當前線程綁定起來 TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder()); } //設置事務對象中的SessionHolder是事務同步的 txObject.getSessionHolder().setSynchronizedWithTransaction(true); } //事務開啓過程當中異常處理 catch (Exception ex) { if (txObject.isNewSession()) { try { //若是Session的事務上激活的,回滾Session的事務 if (session.getTransaction().isActive()) { session.getTransaction().rollback(); } } catch (Throwable ex2) { logger.debug("Could not rollback Session after failed transaction begin", ex); } finally { //關閉Session SessionFactoryUtils.closeSession(session); } } throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); } } //事務掛起 protected Object doSuspend(Object transaction) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; //把當前的SessionHolder從線程中和事務對象中釋放 txObject.setSessionHolder(null); //解析SessionHolder和線程的綁定 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); txObject.setConnectionHolder(null); ConnectionHolder connectionHolder = null; //解除數據源和線程的綁定 if (getDataSource() != null) { connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResource(getDataSource()); } return new SuspendedResourcesHolder(sessionHolder, connectionHolder); } //事務恢復 protected void doResume(Object transaction, Object suspendedResources) { SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; //若是事務管理器中有SessionFactory if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { //解除SessionFactory和當前線程的綁定 TransactionSynchronizationManager.unbindResource(getSessionFactory()); } //若是事務管理器中沒有SessionFactory,則將Session和當前線程綁定 TransactionSynchronizationManager.bindResource(getSessionFactory(), resourcesHolder.getSessionHolder()); if (getDataSource() != null) { TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder()); } } //準備提交 protected void prepareForCommit(DefaultTransactionStatus status) { //若是事務配置爲FlushBeforeCommit,而且是新事務 if (this.earlyFlushBeforeCommit && status.isNewTransaction()) { //獲取事務對象 HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); //回去事務對象中的Session Session session = txObject.getSessionHolder().getSession(); //若是Session的刷新模式不低於COMMIT if (!session.getFlushMode().lessThan(FlushMode.COMMIT)) { logger.debug("Performing an early flush for Hibernate transaction"); try { //刷新Session session.flush(); } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } finally { //把Session的刷新模式設置爲MANUAL session.setFlushMode(FlushMode.MANUAL); } } } } //提交處理 protected void doCommit(DefaultTransactionStatus status) { //獲取當前的Hibernate事務對象 HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Committing Hibernate transaction on Session [" +SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]"); } try { //經過Hibernate事務完成提交 txObject.getSessionHolder().getTransaction().commit(); } catch (org.hibernate.TransactionException ex) { throw new TransactionSystemException("Could not commit Hibernate transaction", ex); } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } } //回滾處理 protected void doRollback(DefaultTransactionStatus status) { //獲取Hibernate事務對象 HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Rolling back Hibernate transaction on Session ["+SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]"); } try { //經過Hibernate事務執行回滾操做 txObject.getSessionHolder().getTransaction().rollback(); } catch (org.hibernate.TransactionException ex) { throw new TransactionSystemException("Could not roll back Hibernate transaction", ex); } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } finally { if (!txObject.isNewSession() && !this.hibernateManagedSession) { //清除事務對象中的Hibernate Session txObject.getSessionHolder().getSession().clear(); } } } …… }
經過上面對Hibernate事務處理器的分析,咱們看到真正執行提交、回滾等事務操做的仍是Hibernate Transaction事務對象,這與單獨直接使用Hibernate沒有什麼區別,只是Spring將其作了通用封裝,更加方便使用。this