首页 > 作文

Spring事务失效场景的详细整理

更新时间:2023-04-05 00:58:00 阅读: 评论:0

目录
前言数据库引擎不支持事物方法不是 public 的自身调用问题不支持事物异常被吃掉异常类型错误总结

前言

项目中用sprin祝酒词大全g的 @transactional 注解控制事务,使用中时常出现事物不生效的场景,本文仅限于日常项目开发中的点滴整理总结,总结以下几点,以备后续参考排查;可能不全,列举出来希望可以帮助有需要的同学,避免踩坑。

数据库引擎不支持事物

这里以 mysql 为例,其 myisam 引擎是不支持事务操作的,innodb 才是支持事务的引擎,一般要支持事务都会使用 innodb。

根据 mysql 的官方文档:

https://dev.mysql.com/doc/refman/5.5/en/storage-engine-tting.html

从 mysql 5.5.5 开始的默认存储引擎是:innodb,之前默认的都是:myisam,所以这点要值得注意,底层引擎不支持事务是硬伤。

没有被 spring 管理

// @rvice (此注解不能去掉)public class accountrviceimpl implements accountrvice {@transactionalpublic void inr(account account) {// inrt account}}

如果此时把 @rvice 注解注释掉,这个类就不会被加载成一个 bean,那这个类就不会被 spring 管理了,事务自然就失效了。

方法不是 public 的

以下来自于spring 官方文档:

when using proxies, you should apply the @transactional annotation only to methods with public visibility. if you do annotate protected, private or桂月 package-visible methods with the @transactional annotation, no error is raid, but the annotated method does not e醉酒妈妈xhibit the configured transactional ttings. consider the u of aspectj (e below) if you need to annotate non-public methods.

意思就是 @transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以考虑开启 aspectj 代理模式。

自身调用问题

看下面代码

@rvicepublic class accountrviceimpl implements accountrvice {public void inrt(account account) {inrtaccount(account);}@transactionalpublic void inrtaccount(account account) {// inrt account}}

inrt方法上面没有加 @transactional 注解,调用有 @transactional 注解的 inrtaccount 方法,inrtaccount 方法上的事务其实是不管用的。

再看下面的代码

@rvicepublic class accountrviceimpl implements accountrvice {@transactionalpublic void inrt(account account) {inrtaccount(account);}@transactional(核工业学院propagation = propagation.requires_new)public void inrtaccount(account account) {// inrt account}}

这次在 inrt 方法上加了 @transactional,inrtaccount 加了 requires_new 新开启一个事务,那么新开的事务管用么?

这两个例子的答案是:不管用!

因为它们发生了自身调用,就调该类自己的方法,而没有经过 spring 的代理类,默认只有在外部调用事务才会生效,这也是老生常谈的经典问题了。

数据源没有配置事物管理器

@beanpublic platformtransactionmanager transactionmanager(datasource datasource) {return new datasourcetransactionmanager(datasource);}

如上面所示,当前数据源若没有配置事务管理器,照样会失效!

不支持事物

@rvicepublic class accountrviceimpl implements accountrvice {@transactionalpublic void inrt(account account) {inrtaccount(account);}@transactional(propagation = propagation.not_supported)public void inrtaccount(account account) {// inrt account}}

propagation.not_supported: 表示不以事务运行,当前若存在事务则挂起,详细的可以参考innodb的事务隔离级别和传播机制。

都主动不支持以事务方式运行了,那事务生效也是白搭!

异常被吃掉

这个是比较常见的场景

@rvice (此注解不能去掉)public class accountrviceimpl implements accountrvice {@transactionalpublic void inr(account account) {try {// inrt account} catch {}}}

把异常吃了,然后又不抛出来,事务就无法回滚!

异常类型错误

@rvice (此注解不能去掉)public class accountrviceimpl implements accountrvice {@transactionalpublic void inr(account account) {try {//除法导数 inrt account} catch {throw new exception("新增错误");}}}

这样事务也是不生效的,因为默认回滚的是:runtimeexception,如果你想触发其他异常的回滚,需要在注解上配置一下,如:

@transactional(rollbackfor = exception.class)

这个配置仅限于 throwable 异常类及其子类。

查阅资料,其他失效的场景需注意:1) 像文件导入数据库,用多线程控制;可参考查询spring 多线程事务的问题 2)springboot+shiro引起事务失效

总结

本文总结了几种事务失效的场景,其实发生最多就是自身调用、异常被吃、异常抛出类型不对这三个了;像文章开头说的那样,本文不一定总结得全,只是根据经验总结常见的事务失效的场景。

到此这篇关于spring事务失效场景的文章就介绍到这了,更多相关spring事务失效场景内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-05 00:57:57,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/5158c48d65d27840e55df609c4fe3cae.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Spring事务失效场景的详细整理.doc

本文 PDF 下载地址:Spring事务失效场景的详细整理.pdf

标签:事务   注解   不支持   异常
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图