spring事务的失效

TransactionDefinitio
7 种传播行为
int PROPAGATION_REQUIRED = 0;

支持当前事务,如果没有则开启新的事务

int PROPAGATION_SUPPORTS=1

支持当前事务,如果当前没有事务,就以非事务方式执行

int PROPAGATION_MANDATORY = 2

支持当前事务, 如果没有事务则会抛出异常。

                                  throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'")
int PROPAGATION_REQUIRES_NEW = 3;创建一个新的事务, 事务相互独立,如果当前存在事务,则中断;它拥有自己的隔离范围, 自己的锁。
int PROPAGATION_NOT_SUPPORTED = 4;以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
int PROPAGATION_NEVER = 5

不支持当前事务,如果存在则直接抛出异常

int PROPAGATION_NESTED = 6

嵌套事务。它是已经存在事务的⼀个真正的⼦事务. 潜套事务开始执⾏时,  它将取得⼀个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的⼀部分, 只有外部事务结束后它才会被提交. (并不是鸡肋的存在)

事务失效的原因

1   必须时public 修饰

2   在同一个类的方法调用。 事务失效, ( 因为走的不是代理对象, 而是代理对象,所以没走DynamicAdvisedInterceptor的逻辑。解决方法: 可以自己依赖自己 )

 3 @Transactional 注解参数rollbackFor 的回滚类,  源码见下面分析

4   数据库引擎不支持事务

5  不正确捕获异常 try catch 

 以下:传播行为的异常

6   使用了传播行为:PROPAGATION_NOT_SUPPORTED

 传播行为的报错

PROPAGATION_MANDATORY    

支持当前事务, 如果没有事务则会抛出异常。

throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'")

 PROPAGATION_REQUIRED

throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");

因为在事务链中, 有多个方法使用了PROPAGATION_REQUIRED 的传播行为,   其中一个方法抛出异常,并将连接设置为 已回滚getConnectionHolder().setRollbackOnly();, 然后使用了方法使用了 try catch 捕获。  提交事务时, 发现已回滚则抛出异常。  (这种情况的解决:可以参考一下嵌套事务的  PROPAGATION_NESTED, 当然具体问题具体分析

TransactionInterceptor在方法体

1.创建事务信息

invokeWithinTransaction 中createTransactionIfNecessary 创建事务信息,TransactionInfo

doGetTransaction() 获取对象DataSourceTransactionObject。类图如下

到这里返回 DefaultTransactionStatus 实例  

方法 doBegin() 则获取数据库来连接, 并绑定当前线程。 

最终 prepareTransactionInfo() 创建事务信息 new  TransactionInfo();并将事务信息绑定线程。

 txInfo.bindToThread(); 如果当前有

TransactionAspectSupport中

private static final ThreadLocal<TransactionInfo> transactionInfoHolder =

                     new NamedThreadLocal<>("Current aspect-driven transaction");

transactionInfoHolder获取事务则直接赋值给当前对象的oldTransactionInfo;新事务信息

会形成一个单向的节点链

2  回滚,抛出异常,并释放资源

对异常回滚的判断,是否需要回滚

 对回滚异常的判断, 判断类RuleBasedTransactionAttribute

回滚异常类的判断

最后采用递归的方式, 对异常的名字进行判断;这也是很有可能事务失效的原因之一。

a.@Transactional(rollbackFor = NullPointerException.class) 获取注解参数rollbackFor 的名字进行判断,exceptionClass.getName().contains(this.exceptionName),且递归深度要小于Integer.MAX_VALUE

b 在满足a条件的基础之上,当winner!=null,且要不属于NoRollbackRuleAttribute 类型,才会事务回滚

c 如果@Transactional 注解参数rollbackFor 为空,则判断为ex instanceof RuntimeException || ex instanceof Error, 否则事务也会失效

 

 释放来连接资源, 并关闭资源

 

3  final 

5  finally  将 transactionInfoHolder

private static final ThreadLocal<TransactionInfo> transactionInfoHolder =

                     new NamedThreadLocal<>("Current aspect-driven transaction")

不管成功还是失败,将transactionInfoHolder的值设置为上一个事务对象oldTransactionInfo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,有几种情况可能导致事务失效。首先,如果方法没有被public修饰或者所在的类没有被Spring管理,那么事务将无法生效。此外,如果方法抛出的异常没有被Spring事务捕捉,或者被同类中的其他方法捕获,也会导致事务失效。另外,如果使用了@Transactional注解,并且设置了propagation属性为PROPAGATION.NEVER,也会导致事务失效。最后,如果在@Transactional注解中设置的rollbackFor属性所指定的异常类型与实际抛出的异常类型不匹配,也会导致事务无法回滚。因此,为了避免事务失效,需要注意以上几个方面的配置和使用。123 #### 引用[.reference_title] - *1* [Spring 事务失效的7种场景](https://blog.csdn.net/jiahao1186/article/details/122484466)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *2* [聊聊spring事务失效的12种场景,太坑了](https://blog.csdn.net/lisu061714112/article/details/120098743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [spring事务失效](https://blog.csdn.net/Aaron_King/article/details/124958059)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值