码迷,mamicode.com
首页 > 编程语言 > 详细

spring 声明式事务源码解析 PROPAGATION_REQUIRES

时间:2020-05-12 16:55:44      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:sar   port   create   nested   重点   ring   关闭   with   连接   

技术图片

 当执行到47行的时候,会开启一个事务,此事务叫最新事务(老大事务),然后执行到51行的时候,老大事务会传播给51行的

userService,具体如何实现,请看我分析:

动态代理调用目标方法:

技术图片

 一直进去会走进 

invokeWithinTransaction 方法,如下图:

技术图片

 技术图片

 重点分析 

TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

如果有 必要就创建事务

 技术图片

 分析得到事务状态对象:status = tm.getTransaction(txAttr);

 技术图片

 如果是第一个service会走到  

if (isExistingTransaction(transaction)) 为假,就跳过走到下面的代码,开始事务,为最新事务(老大事务),开启事务的同事,会创立一个新的连接,connection
,然后把connection封装到connectionHolder里面,然后把此connnectionHolder放入 threadLocal里面,设置此老大事务为激活状态,并且设置事务状态newTransactin
为true,表示是老大事务。然后运行目标方法,目标方法里面由于 又有另外一个userService, 还是会进入事务的代理代码,会到
if (isExistingTransaction(transaction)) 此时这参数transactin是之前从threadLoacl里面拿到的事务,是之前老大事务留下来的一些属性,所以会任务此时是会存在的,
也就是我们认为的如果当前有事务,就用当前事务,就会进入if条件,走进去
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation ‘never‘");
}

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
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() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}

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 =
prepareTransactionStatus(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.
return startTransaction(definition, transaction, debugEnabled, null);
}
}

进入
 return startTransaction(definition, transaction, debugEnabled, suspendedResources);

技术图片

 

 

进入 doBegin

技术图片

 开启事务,最主要是把connectin自动提交关闭 即代码 

con.setAutoCommit(false);
走完事务代码,然后走目标方法userService,走完以后,由于userService用的事务不是老大事务,所以在执行完目标方法后,提交事务的时候,会判断
状态是不是老大事务,如果不是老大事务就跳过提交(commit)的代码,老大事务判断依据是 newTransaction==true,以及是不是激活状态。然后就会回到
itemService,这个service的目标代码走完以后,就会会到事务代码的提交事务操作,这个时候由于itemService是老大事务,就提交(conmmit),如果在
执行目标方法的时候发生运行时异常,就会进入catch代码块,回滚操作.

spring 声明式事务源码解析 PROPAGATION_REQUIRES

标签:sar   port   create   nested   重点   ring   关闭   with   连接   

原文地址:https://www.cnblogs.com/jingzhi-sksk/p/12877017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!