@Transactional事务几点注意

本文详细介绍了在软件开发过程中如何正确地使用事务管理,包括在哪些情况下需要考虑事务、如何避免常见错误,以及在不同环境下事务的有效性和限制条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里面有几点需要大家留意:
A. 一个功能是否要事务,必须纳入设计、编码考虑。不能仅仅完成了基本功能就ok。
B. 如果加了事务,必须做好开发环境测试(测试环境也尽量触发异常、测试回滚),确保事务生效。
C. 以下列了事务使用过程的注意事项,请大家留意。
1. 不要在接口上声明@Transactional ,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。
2.不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。故@Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。
3.使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)
4.使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,但事务无效。
5.经过在ICORE-CLAIM中测试,效果如下:
A.抛出受查异常XXXException,事务会回滚。
B.抛出运行时异常NullPointerException,事务会回滚。
C.Quartz中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
D.异步任务中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
E.在action中加上@Transactional,不会回滚。切记不要在action中加上事务。
F.在service中加上@Transactional,如果是action直接调该方法,会回滚,如果是间接调,不会回滚。(即上文3提到的)
G.在service中的private加上@Transactional,事务不会回滚。
### @Transactional 注解事务失效解决方案 #### 方法级别的代理问题 当 `@Transactional` 注解的方法在同一类内被另一个方法调用时,由于 Spring AOP 使用的是基于代理的方式,内部调用不会触发代理逻辑,因此事务管理不起作用[^2]。 为了修复这个问题,可以通过以下几种方式之一: 1. **重构代码结构** 将涉及事务操作的方法移动到不同的服务类中。这样可以确保每次调用都经过代理对象处理,从而正常启动事务。 2. **使用编程式事务管理** 如果确实需要保持原有设计模式不变,则可考虑采用编程式的事务控制替代声明式注解。这通常涉及到手动获取 TransactionManager 并显式定义边界条件。 3. **引入外部接口访问** 创建一个额外的服务层或组件专门用于暴露公共 API 给其他模块调用;而原业务逻辑则作为私有成员函数仅限于此类内部交互。 ```java @Service public class MyService { private final MyService self; public MyService() { this.self = null; } @Autowired(required=false) public void setSelf(MyService self) {this.self=self;} // 调用方应始终通过self实例来间接调用带@Transactional的方法 } ``` #### 配置文件设置不当 如果应用程序上下文中缺少必要的 Bean 定义或者配置错误也可能造成 `@Transactional` 不起效。确认已正确启用了 AspectJ 或者 JDK 动态代理机制,并且指定了合适的切面表达式匹配目标 bean 和其上的方法[^3]。 另外需要注意的是,默认情况下只有运行期异常才会引起回滚行为,编译器抛出的 checked exception 是不会自动触发 rollback 的除非特别指定属性参数 `rollbackFor` 来扩大范围。 #### 数据源连接池配置失误 某些数据库驱动程序可能具有自己的默认隔离级别设定或者其他特性影响到了实际执行效果。检查数据源初始化脚本以及相关环境变量是否合理配置,必要时调整这些选项以适应具体需求。 最后提醒一点,在多线程环境下并发修改共享资源时要格外小心,即使有了良好的持久化层保护措施也不能完全排除潜在风险。建议深入理解所使用的框架文档并遵循最佳实践指南来进行开发工作。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值