技术开发 频道

Spring声明式事务管理源码解读


接着我们重点再回头看一下createTransactionIfNecessary方法里的这一句:
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
接着我们就应该去看看这个getTransaction方法了,假设我们是使用hibernate3,其他类似。看getTransaction之前我们来看一下这两类和一个接口
接口PlatformTransactionManager
抽象类public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager
类public class HibernateTransactionManager extends AbstractPlatformTransactionManager,很明显,这里有一个方法模板模式。
那我们看一下AbstractPlatformTransactionManager中得getTransaction方法:

代码
 
  1. public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {   
  2.         Object transaction = doGetTransaction();//抽象方法,也需要子类实现,这个方法同样很重要   
  3.   
  4.         // Cache debug flag to avoid repeated checks.   
  5.         boolean debugEnabled = logger.isDebugEnabled();   
  6.         if (debugEnabled) {   
  7.             logger.debug("Using transaction object [" + transaction + "]");   
  8.         }   
  9.   
  10.         if (definition == null) {   
  11.             // Use defaults if no transaction definition given.   
  12.             definition = new DefaultTransactionDefinition();   
  13.         }   
  14.   
  15.         if (isExistingTransaction(transaction)) {   
  16.             // Existing transaction found -> check propagation behavior to find out how to behave.   
  17.             return handleExistingTransaction(definition, transaction, debugEnabled);   
  18.         }   
  19.   
  20.         // Check definition settings for new transaction.   
  21.         if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {   
  22.             throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());   
  23.         }   
  24.   
  25.         // No existing transaction found -> check propagation behavior to find out how to behave.   
  26.         if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {   
  27.             throw new IllegalTransactionStateException(   
  28.                     "Transaction propagation 'mandatory' but no existing transaction found");   
  29.         }   
  30.         else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||   
  31.                 definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||   
  32.             definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {   
  33.             if (debugEnabled) {   
  34.                 logger.debug("Creating new transaction with name [" + definition.getName() + "]");   
  35.             }   
  36.             doBegin(transaction, definition);   
  37.             boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);   
  38.             return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);   
  39.         }   
  40.         else {   
  41.             // Create "empty" transaction: no actual transaction, but potentially synchronization.   
  42.             boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);   
  43.             return newTransactionStatus(definition, nullfalse, newSynchronization, debugEnabled, null);   
  44.         }   
  45.     }  
上面的代码很多地方都有解释,所以很好理解,这段代码的关键部分在doBegin(transaction,definition)这里(这是一个抽象方法,子类必须实现这个方法,
具体依赖于抽象,这个是对方法模板模式的一个概括。),前面讲到我们假设是使用hibernate,那么就看看HibernateTransactionManager这个类吧,doBegin里的参数1,transaction其实是HibernateTransactionObject的一个实例,这个实例里主要存放的就是sessionholder,sessionholder里存放的就是开始事务的session和transaction对象,如果之前没有sessionholder存放到线程中,那么这个HibernateTransactionObject的实例的属性其实是空的,这一点可以在doBegin方法的实现中看出来
代码
 
  1. protected void doBegin(Object transaction, TransactionDefinition definition) {   
  2.         if (getDataSource() != null && TransactionSynchronizationManager.hasResource(getDataSource())) {   
  3.             throw new IllegalTransactionStateException(   
  4.                     "Pre-bound JDBC Connection found - HibernateTransactionManager does not support " +   
  5.                     "running within DataSourceTransactionManager if told to manage the DataSource itself. " +   
  6.                     "It is recommended to use a single HibernateTransactionManager for all transactions " +   
  7.                     "on a single DataSource, no matter whether Hibernate or JDBC access.");   
  8.         }   
  9.   
  10.         Session session = null;   
  11.   
  12.         try {   
  13.             HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;   
  14.             if (txObject.getSessionHolder() == null) {   
  15.                 Interceptor entityInterceptor = getEntityInterceptor();   
  16.                 Session newSession = (entityInterceptor != null ?   
  17.                         getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());   
  18.                 if (logger.isDebugEnabled()) {   
  19.                     logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");   
  20.                 }   
  21.                 txObject.setSessionHolder(new SessionHolder(newSession), true);  
}//我们看到,如果传进来的transaction中并没有存放sessionholder,那么就新建一个session,放到新的sessionholder中,再放到HibernateTransactionObject的实例中去,顺便说一下,这个变量的名字取得真是差,虽然是Juergen Hoeller写的,也要批一下,搞得别人会以为是Transaction的实例

 

 

代码
0
相关文章