Spring框架学习【Spring具体事务处理器的实现】

1.Spring的事务处理中,通用的事务处理流程框架是由抽象事务管理器AbstractPlatformTransactionManager来提供的,而具体的底层事务处理实现,由PlatformTransactionManager的具体实现类来实现,如 DataSourceTransactionManager JtaTransactionManager HibernateTransactionManager等。我们以Spring中最常用的DataSourceTransactionManager HibernateTransactionManager为例,来分析具体事务处理器的底层实现事务创建、提交和回滚的处理操作。

2.AbstractPlatformTransactionManager抽象事物处理器:

上一篇博客中,我们已经分析了抽象事物管理器AbstractPlatformTransactionManager的源码,了解它实现了PlatformTransactionManager平台事务管理器接口,提供了一系列设计好的事务模板方法,如事务提交、回滚等,这些模板方法的具体实现由具体的事务处理器来提供。

3.DataSourceTransactionManager事务处理器的实现:

DataSourceTransactionManager数据源事务处理器是针对JDBC连接提供的事务处理器实现,即数据源事务处理器把数据库Connection连接和当前线程进行绑定,通过直接调用数据库连接Connection的提交和回滚方法实现事务的提供和回滚处理。其源码如下:

[java] view plaincopyprint?
  1. public class DataSourceTransactionManager extends AbstractPlatformTransactionManager  
  2.         implements ResourceTransactionManager, InitializingBean {  
  3.     //注入数据源   
  4.     private DataSource dataSource;  
  5. //数据源事务处理器默认构造方法,创建一个数据源事务处理器实例,并设置允许嵌套事务   
  6.     public DataSourceTransactionManager() {  
  7.         setNestedTransactionAllowed(true);  
  8.     }  
  9.     //根据给定数据源,创建一个数据源事务处理器实例   
  10.     public DataSourceTransactionManager(DataSource dataSource) {  
  11.         this();  
  12.         setDataSource(dataSource);  
  13.         afterPropertiesSet();  
  14.     }  
  15.     //设置数据源   
  16.     public void setDataSource(DataSource dataSource) {  
  17.         if (dataSource instanceof TransactionAwareDataSourceProxy) {  
  18.             //如果数据源是一个事务包装数据源代理,则获取事务包装代理的目标数据源    
  19.             this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource();  
  20.         }  
  21.         else {  
  22.             this.dataSource = dataSource;  
  23.         }  
  24.     }  
  25.     //获取数据源   
  26.     public DataSource getDataSource() {  
  27.         return this.dataSource;  
  28.     }  
  29.     //数据源事务处理器对象构造方法的回调函数   
  30.     public void afterPropertiesSet() {  
  31.         if (getDataSource() == null) {  
  32.             throw new IllegalArgumentException("Property ‘dataSource‘ is required");  
  33.         }  
  34.     }  
  35. public Object getResourceFactory() {  
  36.         return getDataSource();  
  37.     }  
  38. //创建事务,对数据库而言,是由Connection来完成事务工作的。该方法把数据库的//Connection对象放到一个ConnectionHolder对象中,然后封装到一个   
  39. //DataSourceTransactionObject对象中   
  40.     protected Object doGetTransaction() {  
  41.         //创建数据源事务对象   
  42.         DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
  43.         //设置数据源事务对象对嵌套事务使用保存点   
  44.         txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  45.         //从事务管理容器中获取存放数据库Connection的对象   
  46.         ConnectionHolder conHolder =  
  47.             (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
  48.         txObject.setConnectionHolder(conHolder, false);  
  49.         return txObject;  
  50.     }  
  51.     //判断是否已经存在事务   
  52.     protected boolean isExistingTransaction(Object transaction) {  
  53.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  54.     //根据存放数据库连接的ConnectionHolder的isTransactionActive属性来判断   
  55.         return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());  
  56.     }  
  57.     //处理事务开始的方法   
  58.     protected void doBegin(Object transaction, TransactionDefinition definition) {  
  59.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  60.         Connection con = null;  
  61.         try {  
  62.             //如果数据源事务对象的ConnectionHolder为null或者是事务同步的   
  63.             if (txObject.getConnectionHolder() == null ||  
  64.         txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
  65.                 //获取当前数据源的数据库连接   
  66.                 Connection newCon = this.dataSource.getConnection();  
  67.                 if (logger.isDebugEnabled()) {  
  68.                     logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");  
  69.                 }  
  70.                 //为数据源事务对象设置ConnectionHolder   
  71.                 txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  
  72.             }  
  73.     //设置数据源事务对象的事务同步    txObject.getConnectionHolder().setSynchronizedWithTransaction(true);   
  74.             //获取数据源事务对象的数据库连接   
  75.             con = txObject.getConnectionHolder().getConnection();  
  76.             //根据数据连接和事务属性,获取数据库连接的事务隔离级别   
  77.             Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
  78.     //为数据源事务对象设置事务隔离级别   
  79.     txObject.setPreviousIsolationLevel(previousIsolationLevel);  
  80.             //如果数据库连接设置了自动事务提交属性,则关闭自动提交   
  81.             if (con.getAutoCommit()) {  
  82.                 //保存数据库连接设置的自动连接到数据源事务对象中   
  83.                 txObject.setMustRestoreAutoCommit(true);  
  84.                 if (logger.isDebugEnabled()) {  
  85.                     logger.debug("Switching JDBC Connection [" + con + "] to manual commit");  
  86.                 }  
  87.                 //设置数据库连接自动事务提交属性为false,即禁止自动事务提交   
  88.                 con.setAutoCommit(false);  
  89.             }  
  90.             //激活当前数据源事务对象的事务配置   
  91.             txObject.getConnectionHolder().setTransactionActive(true);  
  92.             //获取事务配置的超时时长   
  93. int timeout = determineTimeout(definition);  
  94. //如果事务配置的超时时长不等于事务的默认超时时长   
  95.             if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
  96.         //数据源事务对象设置超时时长   
  97.         txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  
  98.             }  
  99.             //把当前数据库Connection和线程绑定   
  100.             if (txObject.isNewConnectionHolder()) {  
  101.         TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());  
  102.             }  
  103.         }  
  104.         catch (Exception ex) {  
  105.             DataSourceUtils.releaseConnection(con, this.dataSource);  
  106.             throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);  
  107.         }  
  108.     }  
  109.     //事务挂起   
  110.     protected Object doSuspend(Object transaction) {  
  111.         //获取事务对象   
  112.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  113.         //将事务对象中的ConnectionHolders设置为null   
  114.         txObject.setConnectionHolder(null);  
  115.         ConnectionHolder conHolder = (ConnectionHolder)  
  116.         //解除事务对象和当前线程的绑定    TransactionSynchronizationManager.unbindResource(this.dataSource);   
  117.         return conHolder;  
  118.     }  
  119.     //事务恢复   
  120.     protected void doResume(Object transaction, Object suspendedResources) {  
  121.         //获取已暂停事务的ConnectionHolder   
  122.         ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;  
  123.         //重新将事务对象和当前线程绑定   
  124.         TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);  
  125.     }  
  126.     //事务提交   
  127.     protected void doCommit(DefaultTransactionStatus status) {  
  128.         //获取事务对象   
  129.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  130.         //通过事务对象获取数据库连接   
  131.         Connection con = txObject.getConnectionHolder().getConnection();  
  132.         if (status.isDebug()) {  
  133.             logger.debug("Committing JDBC transaction on Connection [" + con + "]");  
  134.         }  
  135.         try {  
  136.             //使用数据库连接手动进行事务提交   
  137.             con.commit();  
  138.         }  
  139.         catch (SQLException ex) {  
  140.             throw new TransactionSystemException("Could not commit JDBC transaction", ex);  
  141.         }  
  142.     }  
  143.     //事务回滚   
  144.     protected void doRollback(DefaultTransactionStatus status) {  
  145.         //获取事务对象   
  146.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  147.         //通过事务对象获取数据库连接   
  148.         Connection con = txObject.getConnectionHolder().getConnection();  
  149.         if (status.isDebug()) {  
  150.             logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");  
  151.         }  
  152.         try {  
  153.             //通过调用数据库连接的回滚方法完成事务回滚操作   
  154.             con.rollback();  
  155.         }  
  156.         catch (SQLException ex) {  
  157.             throw new TransactionSystemException("Could not roll back JDBC transaction", ex);  
  158.         }  
  159.     }  
  160.     //设置回滚   
  161.     protected void doSetRollbackOnly(DefaultTransactionStatus status) {  
  162.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  163.         if (status.isDebug()) {  
  164.             logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +  
  165.                     "] rollback-only");  
  166.         }  
  167.         txObject.setRollbackOnly();  
  168.     }  
  169.     //操作完成之后清除操作   
  170.     protected void doCleanupAfterCompletion(Object transaction) {  
  171.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  172.         //移除当前线程绑定的ConnectionHolder   
  173.         if (txObject.isNewConnectionHolder()) {  
  174.     TransactionSynchronizationManager.unbindResource(this.dataSource);  
  175.         }  
  176.         Connection con = txObject.getConnectionHolder().getConnection();  
  177.         try {  
  178.         //如果事务对象保存了自动事务提交属性,则设置数据库连接的自动事务提交属性   
  179.             if (txObject.isMustRestoreAutoCommit()) {  
  180.                 con.setAutoCommit(true);  
  181.             }  
  182.             //事务结束后重置数据库连接   
  183.             DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());  
  184.         }  
  185.         catch (Throwable ex) {  
  186.             logger.debug("Could not reset JDBC Connection after transaction", ex);  
  187.         }  
  188.         //如果事务对象中有新的ConnectionHolder    
  189.         if (txObject.isNewConnectionHolder()) {  
  190.             if (logger.isDebugEnabled()) {  
  191.                 logger.debug("Releasing JDBC Connection [" + con + "] after transaction");  
  192.             }  
  193.             //释放数据库连接   
  194.             DataSourceUtils.releaseConnection(con, this.dataSource);  
  195.         }  
  196.         //清除事务对象的ConnectionHolder   
  197.         txObject.getConnectionHolder().clear();  
  198.     }  
  199. //数据源事务对象,内部类   
  200.     private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {  
  201.         //是否有新的ConnectionHolder   
  202.         private boolean newConnectionHolder;  
  203.         //是否保存自动提交   
  204.         private boolean mustRestoreAutoCommit;  
  205.         //设置ConnectionHolder   
  206.         public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {  
  207.             //为父类JdbcTransactionObjectSupport设置ConnectionHolder   
  208.             super.setConnectionHolder(connectionHolder);  
  209.             this.newConnectionHolder = newConnectionHolder;  
  210.         }  
  211.         public boolean isNewConnectionHolder() {  
  212.             return this.newConnectionHolder;  
  213.         }  
  214.         //调用父类JdbcTransactionObjectSupport的相关方法,查询收费存在事务   
  215.         public boolean hasTransaction() {  
  216.             return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive());  
  217.         }  
  218.         //设置是否保存自动提交   
  219.         public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {  
  220.             this.mustRestoreAutoCommit = mustRestoreAutoCommit;  
  221.         }  
  222.         public boolean isMustRestoreAutoCommit() {  
  223.             return this.mustRestoreAutoCommit;  
  224.         }  
  225.         //设置数据库连接在操作失败是,是否只回滚处理   
  226.         public void setRollbackOnly() {  
  227.             getConnectionHolder().setRollbackOnly();  
  228.         }  
  229.         public boolean isRollbackOnly() {  
  230.             return getConnectionHolder().isRollbackOnly();  
  231.         }  
  232.     }  
  233. }  

通过上述对数据源事务处理器的源码分析,我们看到,事务的提交、回滚等操作是通过直接调用数据库连接Connection的提交和回滚方法实现的,由于自动事务提交对应用程序性能影响很大,因此在进行事务提交时,我们首先禁止数据库连接的自动事务提交,事务提供操作通过手动实现。

4.HibernateTransactionManager事务处理器的实现:

相对于数据源的事务处理器来说,Hibernate的事务处理器相对要复杂一些,它是通过对Hibernate的会话Session的管理来完成事务处理实现的。Hibernate事务处理器的事务处理相关源码如下:

[java] view plaincopyprint?
  1. public class HibernateTransactionManager extends AbstractPlatformTransactionManager  
  2.         implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {  
  3.     ……  
  4.     //获取Hibernate事务   
  5.     protected Object doGetTransaction() {  
  6.         //创建Hibernate事务对象   
  7.         HibernateTransactionObject txObject = new HibernateTransactionObject();  
  8.         //根据是否允许嵌套事务设置事务对象是否允许保存点   
  9.         txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  10.         //从线程中获取SessionHolder,SessionHolder是在事务开始时与线程绑定的。   
  11.         SessionHolder sessionHolder =  
  12.                 (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());  
  13.         //如果获取到的SessionHolder不为null   
  14.         if (sessionHolder != null) {  
  15.             if (logger.isDebugEnabled()) {  
  16.                 logger.debug("Found thread-bound Session [" +  
  17.                 SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");  
  18.             }  
  19.             //把获取到的SessionHolder设置到Hibernate事务对象中   
  20.             txObject.setSessionHolder(sessionHolder);  
  21.         }  
  22.         //如果当前Hibernate事务处理器有被管理的Hibernate Session   
  23.         else if (this.hibernateManagedSession) {  
  24.             try {  
  25.                 //获取当前的Hibernate Session   
  26.                 Session session = getSessionFactory().getCurrentSession();  
  27.                 if (logger.isDebugEnabled()) {  
  28.                     logger.debug("Found Hibernate-managed Session [" +  
  29.                             SessionFactoryUtils.toString(session) + "] for Spring-managed transaction");  
  30.                 }  
  31.                 //设置Hibernate事务对象已经存在指定的Session   
  32.                 txObject.setExistingSession(session);  
  33.             }  
  34.             catch (HibernateException ex) {  
  35.                 throw new DataAccessResourceFailureException(  
  36.                         "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);  
  37.             }  
  38.         }  
  39.         //如果获取到的数据源不为null   
  40.         if (getDataSource() != null) {  
  41.             //将获取到的数据源和当前线程绑定   
  42.             ConnectionHolder conHolder = (ConnectionHolder)  
  43.     TransactionSynchronizationManager.getResource(getDataSource());  
  44.             txObject.setConnectionHolder(conHolder);  
  45.         }  
  46.         return txObject;  
  47.     }  
  48.     //是否已存在事务   
  49.     protected boolean isExistingTransaction(Object transaction) {  
  50.         HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;  
  51. //根据事务对象是否存在Spring管理的事务,或者通过判断是否存在Hibernate //Session或者事务对象中有被Hibernate管理的事务   
  52.         return (txObject.hasSpringManagedTransaction() ||  
  53.                 (this.hibernateManagedSession && txObject.hasHibernateManagedTransaction()));  
  54.     }  
  55.     //处理事务开始   
  56.     protected void doBegin(Object transaction, TransactionDefinition definition) {  
  57.         //获取事务对象   
  58.         HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;  
  59.         //如果事务对象有ConnectionHolder,且事务对象的数据库连接不是事务同步的   
  60.         if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
  61.             throw new IllegalTransactionStateException(  
  62.                     "Pre-bound JDBC Connection found! HibernateTransactionManager does not support " +  
  63.                     "running within DataSourceTransactionManager if told to manage the DataSource itself. " +  
  64.                     "It is recommended to use a single HibernateTransactionManager for all transactions " +  
  65.                     "on a single DataSource, no matter whether Hibernate or JDBC access.");  
  66.         }  
  67.         Session session = null;  
  68.         try {  
  69.             //如果事务对象的SessionHolder为null,或者事务对象Hibernate   
  70.             //Session是事务同步的   
  71.             if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {  
  72.                 //获取Hibernate事务处理器中的实体拦截器   
  73.                 Interceptor entityInterceptor = getEntityInterceptor();  
  74.                 //获取Hibernate Session,如果实体拦截器不为null,则打开指定   
  75. //实体拦截器的Session,如果实体拦截器为null,则打开新Session   
  76.                 Session newSession = (entityInterceptor != null ?  
  77.                     getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());  
  78.                 if (logger.isDebugEnabled()) {  
  79.                     logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) +  
  80.                             "] for Hibernate transaction");  
  81.                 }  
  82.                 //将获取的Hibernate Session设置到事务对象中   
  83.                 txObject.setSession(newSession);  
  84.             }  
  85. //如果Hibernate事务处理器中的SessionHolder不为null,则   
  86. //获取SessionHolder中已有的Hibernate Session   
  87.             session = txObject.getSessionHolder().getSession();  
  88.             //允许为JDBC连接改变事务设置   
  89.             if (this.prepareConnection && isSameConnectionForEntireSession(session)) {  
  90.                 if (logger.isDebugEnabled()) {  
  91.                     logger.debug(  
  92.                             "Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");  
  93.                 }  
  94.                 //获取Session连接   
  95.                 Connection con = session.connection();  
  96.                 //获取事务的隔离级别   
  97.                 Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
  98.             //设置事务对象的事务隔离级别 txObject.setPreviousIsolationLevel(previousIsolationLevel);   
  99.             }  
  100.             //不允许为JDBC连接改成事务设置   
  101.             else {  
  102.                 //如果事务隔离级别不是默认事务隔离级别   
  103.                 if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {  
  104.                     throw new InvalidIsolationLevelException(  
  105.                             "HibernateTransactionManager is not allowed to support custom isolation levels: " +  
  106.                             "make sure that its ‘prepareConnection‘ flag is on (the default) and that the " +  
  107.                             "Hibernate connection release mode is set to ‘on_close‘ (SpringTransactionFactory‘s default). " +  
  108.                             "Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " +  
  109.                             "Hibernate properties should *not* include a ‘hibernate.transaction.factory_class‘ property!");  
  110.                 }  
  111.                 if (logger.isDebugEnabled()) {  
  112.                     logger.debug(  
  113.                             "Not preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");  
  114.                 }  
  115.             }  
  116.             //如果事务是只读,且事务对象是新的Hibernate Session   
  117.             if (definition.isReadOnly() && txObject.isNewSession()) {  
  118.                 //设置Hibernate Session刷新模式为手动   
  119.                 session.setFlushMode(FlushMode.MANUAL);  
  120.             }  
  121.             //如果事务是非只读的,且事务对象不是新Hibernate Session   
  122.             if (!definition.isReadOnly() && !txObject.isNewSession()) {  
  123.                 //或者Hibernate的刷新模式   
  124.                 FlushMode flushMode = session.getFlushMode();  
  125.                 //设置Session的刷新模式   
  126.                 if (flushMode.lessThan(FlushMode.COMMIT)) {  
  127.                     session.setFlushMode(FlushMode.AUTO);  
  128.                 //为事务对象设置刷新模式   txObject.getSessionHolder().setPreviousFlushMode(flushMode);   
  129.                 }  
  130.             }  
  131.             Transaction hibTx;  
  132.             //获取事务超时时长   
  133.             int timeout = determineTimeout(definition);  
  134.             //如果事务配置的超时时长不是事务默认超时时长   
  135.             if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
  136.                 //获取Hibernate Session事务   
  137.                 hibTx = session.getTransaction();  
  138.                 //为事务对象设置超时时长   
  139.                 hibTx.setTimeout(timeout);  
  140.                 //开启事务   
  141.                 hibTx.begin();  
  142.             }  
  143.             //如果事务配置的超时时长是默认超时时长   
  144.             else {  
  145.                 //通过Hibernate Session直接开启事务   
  146.                 hibTx = session.beginTransaction();  
  147.             }  
  148.             //把事务设置到事务对象的SessionHolder中,并且线程绑定   
  149.             txObject.getSessionHolder().setTransaction(hibTx);  
  150.             //如果数据源不为null,即设置了数据源   
  151.             if (getDataSource() != null) {  
  152.                 //使用Hibernate Session打开数据库连接   
  153.                 Connection con = session.connection();  
  154.                 //创建ConnectionHolder   
  155.                 ConnectionHolder conHolder = new ConnectionHolder(con);  
  156.                 //设置超时时长   
  157.                 if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
  158.                     conHolder.setTimeoutInSeconds(timeout);  
  159.                 }  
  160.                 if (logger.isDebugEnabled()) {  
  161.                     logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");  
  162.                 }  
  163.             //将数据源和JDBC ConnectionHolder绑定到当前线程 TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);   
  164.                 //将创建的JDBC ConnectionHolder设置到事务对象中   
  165.                 txObject.setConnectionHolder(conHolder);  
  166.             }  
  167.             //如果事务对象中的SessionHolder是新的   
  168.             if (txObject.isNewSessionHolder()) {  
  169.             //当SessionHolder和当前线程绑定起来   TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());   
  170.             }  
  171.         //设置事务对象中的SessionHolder是事务同步的   txObject.getSessionHolder().setSynchronizedWithTransaction(true);   
  172.         }  
  173.         //事务开启过程中异常处理   
  174.         catch (Exception ex) {  
  175.             if (txObject.isNewSession()) {  
  176.                 try {  
  177.                     //如果Session的事务上激活的,回滚Session的事务   
  178.                     if (session.getTransaction().isActive()) {  
  179.                         session.getTransaction().rollback();  
  180.                     }  
  181.                 }  
  182.                 catch (Throwable ex2) {  
  183.                     logger.debug("Could not rollback Session after failed transaction begin", ex);  
  184.                 }  
  185.                 finally {  
  186.                     //关闭Session   
  187.                     SessionFactoryUtils.closeSession(session);  
  188.                 }  
  189.             }  
  190.             throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);  
  191.         }  
  192.     }  
  193.     //事务挂起   
  194.     protected Object doSuspend(Object transaction) {  
  195.         HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;  
  196.         //把当前的SessionHolder从线程中和事务对象中释放   
  197.         txObject.setSessionHolder(null);  
  198.         //解析SessionHolder和线程的绑定   
  199.         SessionHolder sessionHolder =  
  200.                 (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory());  
  201.         txObject.setConnectionHolder(null);  
  202.         ConnectionHolder connectionHolder = null;  
  203.         //解除数据源和线程的绑定   
  204.         if (getDataSource() != null) {  
  205.             connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResource(getDataSource());  
  206.         }  
  207.         return new SuspendedResourcesHolder(sessionHolder, connectionHolder);  
  208.     }  
  209.     //事务恢复   
  210.     protected void doResume(Object transaction, Object suspendedResources) {  
  211.         SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources;  
  212.         //如果事务管理器中有SessionFactory   
  213.         if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {  
  214.     //解除SessionFactory和当前线程的绑定   
  215.     TransactionSynchronizationManager.unbindResource(getSessionFactory());  
  216.         }  
  217.     //如果事务管理器中没有SessionFactory,则将Session和当前线程绑定 TransactionSynchronizationManager.bindResource(getSessionFactory(), resourcesHolder.getSessionHolder());   
  218.         if (getDataSource() != null) {  
  219.         TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder());  
  220.         }  
  221.     }  
  222.     //准备提交   
  223.     protected void prepareForCommit(DefaultTransactionStatus status) {  
  224.         //如果事务配置为FlushBeforeCommit,并且是新事务   
  225.         if (this.earlyFlushBeforeCommit && status.isNewTransaction()) {  
  226.             //获取事务对象   
  227.             HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();  
  228.             //回去事务对象中的Session   
  229.             Session session = txObject.getSessionHolder().getSession();  
  230.             //如果Session的刷新模式不低于COMMIT   
  231.             if (!session.getFlushMode().lessThan(FlushMode.COMMIT)) {  
  232.                 logger.debug("Performing an early flush for Hibernate transaction");  
  233.                 try {  
  234.                     //刷新Session   
  235.                     session.flush();  
  236.                 }  
  237.                 catch (HibernateException ex) {  
  238.                     throw convertHibernateAccessException(ex);  
  239.                 }  
  240.                 finally {  
  241.                     //把Session的刷新模式设置为MANUAL   
  242.                     session.setFlushMode(FlushMode.MANUAL);  
  243.                 }  
  244.             }  
  245.         }  
  246.     }  
  247.     //提交处理   
  248.     protected void doCommit(DefaultTransactionStatus status) {  
  249.         //获取当前的Hibernate事务对象   
  250.         HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();  
  251.         if (status.isDebug()) {  
  252.             logger.debug("Committing Hibernate transaction on Session [" +SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");  
  253.         }  
  254.         try {  
  255.             //通过Hibernate事务完成提交   
  256.             txObject.getSessionHolder().getTransaction().commit();  
  257.         }  
  258.         catch (org.hibernate.TransactionException ex) {  
  259.             throw new TransactionSystemException("Could not commit Hibernate transaction", ex);  
  260.         }  
  261.         catch (HibernateException ex) {  
  262.             throw convertHibernateAccessException(ex);  
  263.         }  
  264.     }  
  265.     //回滚处理   
  266.     protected void doRollback(DefaultTransactionStatus status) {  
  267.         //获取Hibernate事务对象   
  268.         HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();  
  269.         if (status.isDebug()) {  
  270.             logger.debug("Rolling back Hibernate transaction on Session ["+SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");  
  271.         }  
  272.         try {  
  273.             //通过Hibernate事务执行回滚操作   
  274.             txObject.getSessionHolder().getTransaction().rollback();  
  275.         }  
  276.         catch (org.hibernate.TransactionException ex) {  
  277.             throw new TransactionSystemException("Could not roll back Hibernate transaction", ex);  
  278.         }  
  279.         catch (HibernateException ex) {  
  280.             throw convertHibernateAccessException(ex);  
  281.         }  
  282.         finally {  
  283.             if (!txObject.isNewSession() && !this.hibernateManagedSession) {  
  284.                 //清除事务对象中的Hibernate Session   
  285.                 txObject.getSessionHolder().getSession().clear();  
  286.             }  
  287.         }  
  288.     }  
  289. ……  
  290.     }  

通过上面对Hibernate事务处理器的分析,我们看到真正执行提交、回滚等事务操作的还是Hibernate Transaction事务对象,这与单独直接使用Hibernate没有什么区别,只是Spring将其做了通用封装,更加方便使用。

Spring框架学习【Spring具体事务处理器的实现】

上一篇:对《java程序员上班那点事》笔者对数组占用内存质疑


下一篇:Photoshop婚纱照片合成:个性化装饰