面试官:问你一个,Spring事务是如何传播的?( 七 )

流程和提交是一样的 , 先是判断有没有回滚点 , 如果有就回到到回滚点并清除该回滚点;如果没有则判断是不是新事务(PROPAGATION_REQUIRED属性下的最外层事务和PROPAGATION_REQUIRES_NEW属性下的事务) , 满足则直接回滚当前事务 。 回滚完成后同样需要清除掉当前的事务状态并恢复挂起的连接 。 另外需要特别注意的是在catch里面调用完回滚逻辑后 , 还通过throw抛出了异常 , 这意味着什么?意味着即使是嵌套事务 , 内层事务的回滚也会导致外层事务的回滚 , 也就是addA的事务也会跟着回滚 。 至此 , 事务的传播原理分析完毕 , 深入看每个方法的实现是很复杂的 , 但如果仅仅是分析各个传播属性对事务的影响 , 则有一个简单的方法 。 我们可以将内层事务切面等效替换掉invocation.proceedWithInvocation方法 , 比如上面两个类的调用可以看作是下面这样:
// addA的事务TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;try { // addB的事务 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try {retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) {// target invocation exception//事务回滚completeTransactionAfterThrowing(txInfo, ex);throw ex; } finally {cleanupTransactionInfo(txInfo); } //事务提交 commitTransactionAfterReturning(txInfo);}catch (Throwable ex) { //事务回滚 completeTransactionAfterThrowing(txInfo, ex); throw ex;}//事务提交commitTransactionAfterReturning(txInfo);这样看是不是很容易就能分析出事务之间的影响以及是提交还是回滚了?下面来看几个实例分析 。
实例分析我再添加一个C类 , 和addC的方法 , 然后在addA里面调用这个方法 。
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;try { // addB的事务 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try {b.addB(); } catch (Throwable ex) {// target invocation exception//事务回滚completeTransactionAfterThrowing(txInfo, ex);throw ex; } //事务提交 commitTransactionAfterReturning(txInfo); // addC的事务 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try {c.addC(); } catch (Throwable ex) {// target invocation exception//事务回滚completeTransactionAfterThrowing(txInfo, ex);throw ex; } //事务提交 commitTransactionAfterReturning(txInfo);}catch (Throwable ex) { //事务回滚 completeTransactionAfterThrowing(txInfo, ex); throw ex;}//事务提交commitTransactionAfterReturning(txInfo);等效替换后就是上面这个代码 , 我们分别来分析 。