博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 事务代码分析
阅读量:6307 次
发布时间:2019-06-22

本文共 5349 字,大约阅读时间需要 17 分钟。

实际上,在spring的事务中,只要该类被设置为了事务代理:
 
拦截器都会创建一个TransactionInfo 对象:
 

TransactionInfo txInfo = new TransactionInfo(txAttr, method);

 
 
而且如果 只要被调用的方法设置了事务属性(txAttr),不管是什么属性都会调用:
 

txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));

 
根据该方法的事务属性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值会有所不同(代码见AbstractPlatformTransactionManager),具体为以下几种情况:
1.当前没有事务时(即以下代码中的((HibernateTransactionObject) transaction).hasTransaction()返回false),会返回以下几种:
 

 

// Check definition settings for new transaction.
  if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
   throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
  }
 
  // No existing transaction found -> check propagation behavior to find out how to behave.
  if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
   throw new IllegalTransactionStateException(
     "Transaction propagation 'mandatory' but no existing transaction found");
  }
  else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
    definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
      definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
   if (debugEnabled) {
    logger.debug("Creating new transaction with name [" + definition.getName() + "]");
   }
   doBegin(transaction, definition);
   boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
   return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
  }
  else {
   // Create "empty" transaction: no actual transaction, but potentially synchronization.
   boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
   return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null);
  }
 
2.当前有事务时

 

private TransactionStatus handleExistingTransaction(
   TransactionDefinition definition, Object transaction, boolean debugEnabled)
   throws TransactionException {
 
  if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
   throw new IllegalTransactionStateException(
     "Transaction propagation 'never' but existing transaction found");
  }
 
  if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
   if (debugEnabled) {
    logger.debug("Suspending current transaction");
   }
   Object suspendedResources = suspend(transaction);
   boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
   return newTransactionStatus(
     definition, null, false, newSynchronization, debugEnabled, suspendedResources);
  }
 
  if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
   if (debugEnabled) {
    logger.debug("Suspending current transaction, creating new transaction with name [" +
      definition.getName() + "]");
   }
   Object suspendedResources = suspend(transaction);
   doBegin(transaction, definition);
   boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
   return newTransactionStatus(
     definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  }
 
  if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
   if (!isNestedTransactionAllowed()) {
    throw new NestedTransactionNotSupportedException(
      "Transaction manager does not allow nested transactions by default - " +
      "specify 'nestedTransactionAllowed' property with value 'true'");
   }
   if (debugEnabled) {
    logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
   }
   if (useSavepointForNestedTransaction()) {
    // Create savepoint within existing Spring-managed transaction,
    // through the SavepointManager API implemented by TransactionStatus.
    // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
    DefaultTransactionStatus status =
      newTransactionStatus(definition, transaction, false, false, debugEnabled, null);
    status.createAndHoldSavepoint();
    return status;
   }
   else {
    // Nested transaction through nested begin and commit/rollback calls.
    // Usually only for JTA: Spring synchronization might get activated here
    // in case of a pre-existing JTA transaction.
    doBegin(transaction, definition);
    boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
    return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
   }
  }
 
最后,txInfo被绑定到当前线程上作为当前事务:
 

txInfo.bindToThread()

 
然后,调用实际的目标类的方法并捕捉异常:
 

 

try {
   // This is an around advice.
   // Invoke the next interceptor in the chain.
   // This will normally result in a target object being invoked.
   retVal = invocation.proceed();
  }
  catch (Throwable ex) {
   // target invocation exception
   doCloseTransactionAfterThrowing(txInfo, ex);
   throw ex;
  }
  finally {
   doFinally(txInfo);
  }
  doCommitTransactionAfterReturning(txInfo);
  return retVal;
 }
 
 
另外一点,TransactionInfo的newTransactionStatus调用时如果参数的不是null,TransactionInfo.hasTransaction()方法返回true;
 
重要提示:
在spring中创建的事务代理类并是目标类的超类,只是一个实现这目标类接口的类,该类会调用目标类的方法,所在如果一个目标类中的方法调用自身的另一个事务方法,另一个方法只是作为普通方法来调用,并不会加入事务机制
 
参考资料:
1.Spring Reference Manual:http://static.springframework.org/spring/docs/1.2.x/reference/index.html
2.Spring API doc:http://static.springframework.org/spring/docs/1.2.x/api/index.html
3.Spring 的源代码

转载于:https://www.cnblogs.com/huapox/archive/2012/09/01/3251478.html

你可能感兴趣的文章
费用登记系统(开发小结)
查看>>
python去除列表最小的元素
查看>>
GCC,GDB,Makefile
查看>>
ubuntu12.10安装jdk1.7
查看>>
[ HDOJ 3826 ] Squarefree number
查看>>
上传本地文件到linux
查看>>
c++中,size_typt, size_t, ptrdiff_t 简介
查看>>
String to Integer (atoi) - 复杂的测试
查看>>
PHP配置图文教程
查看>>
常用英语
查看>>
关于flask登录视图报错AttributeError: '_AppCtxGlobals' object has no attribute 'user'
查看>>
Delegate,Action,Func,匿名方法,匿名委托,事件
查看>>
wscript.shell 使用
查看>>
oracle数据查询
查看>>
VMWare 安装Ubuntu 16.04
查看>>
微服务开发过程中需要注意的若干事项(转载)
查看>>
一些误差的概念
查看>>
Network Saboteur (DFS)
查看>>
ubuntu 16.04 启用root用户方法
查看>>
html5 canvas图片马赛克
查看>>