小程序可以用手机网站吗,黄页网络的推广网站有哪些类型,网站开发实训心得800字,时事新闻热点场景如下#xff1a; A_Bean 中的方法a()中调用B_Bean的b();方法都开启了事务#xff0c;使用的默认的事务传递机制#xff08;即#xff1a;属于同一事务#xff09;#xff1b;
如下两种场景会存在较大的差异#xff1a;
在b()方法中出现了异常#xff0c;在b()中进…场景如下 A_Bean 中的方法a()中调用B_Bean的b();方法都开启了事务使用的默认的事务传递机制即属于同一事务
如下两种场景会存在较大的差异
在b()方法中出现了异常在b()中进行捕获并处理且没有抛出新的异常事务最终会进行提交在b()方法中出现了异常在a()中进行捕获并处理且没有抛出新的异常那么事务最终会如何呢—— 先给结论事务回滚
这个小差异平时编程的过程比较难留意到会简单认为当某个方法上面开启了事务并且当前方法没有抛出任何异常最终方法上面的事务一定会提交。其实这里是存在认知错误的。
code如下
SpringBootTest
public class TransactionTest {Autowiredprivate A a;Testvoid testTransaction() throws Exception {a.a();}}Service
public class A {Autowiredprivate B b;Transactionalpublic void a() {try {b.b();} catch (Exception e) {log.error(b执行异常进行捕获且不抛出异常);}// for some db operation}}Service
public class B {Transactionalpublic void b() {// for some db operationthrow new RuntimeException(b-error);}
}} 为何错误
当 a() 方法调用 b() 方法时如果两个方法都开启了事务且采用默认的事务传播行为即事务嵌套b() 方法的事务会加入到 a() 方法的事务中成为同一个事务。那么b()中出现异常b中没有捕获而在a中捕获实则已经触发b()的事务处理异常的逻辑。而a、b方法执行又同属一个事务在b异常被事务管理器感知到后就会将当前事务标记为rollback那么即使a最终没有感知到异常最终a正常执行完毕后a上面的事务管理逻辑也不会将事务进行提交而是采取回滚的决定
源码分析
当一个事务方法执行出现异常时比如b()执行抛出异常时
org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing
org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback
org.springframework.transaction.support.AbstractPlatformTransactionManager#processRollback
org.springframework.jdbc.datasource.DataSourceTransactionManager#doSetRollbackOnly
org.springframework.jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setRollbackOnly
org.springframework.transaction.support.ResourceHolderSupport#setRollbackOnly 当a()正常执行完毕准备提交事务时
org.springframework.transaction.interceptor.TransactionInterceptor#invoke
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning
org.springframework.transaction.support.AbstractPlatformTransactionManager#commit org.springframework.transaction.support.SmartTransactionObject#isRollbackOnly
org.springframework.jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#isRollbackOnly
a执行完毕会进行判断 最终还是会进行事务的回滚 在 Spring 中当事务被标记为 rollback-only 时它会通知事务管理器表示事务应该回滚。即使没有抛出新的异常一旦事务被标记为 rollback-only最终事务仍然会回滚。
因此在你的情况下如果 b() 方法中出现异常在 a() 方法中进行了捕获并处理但是事务在 b() 方法中被标记为 rollback-only最终会导致 a() 方法的事务回滚。
如果有这种需要该如何处理
如题a事务嵌套b事务不管b事务是否执行成功只有a中最终没有抛出异常那么就需要将a提交做到a事务不受内部嵌套事务的影响该如何
修改b事务的传播配置