Spring 事务不回滚

熬夜没好处啊!

刚才做Spring的测试不回滚,总结了一下可能的原因:

1、无论是<aop:advisor还是使用的注解或者pojo的aop,总之,可能配置或者使用的不对,最基本的原因。

2、你自己捕获异常了,没有抛出去,让spring知道

3、你调用的方法不是自己的,而是继承的(让继承的类实现了你的一些接口,且,你没有重载),spring是不会去包裹那个父类的方法,也包裹不到(这个观点,没有绝对证实哈)。就是,spring只管你目前调用的类的能看得到的方法。解决的方式是,在你的daosupport上加上@Transactional,也可以解决。还要清楚一点,最子类的事务声明才是有效的,如果最子类没有声明,会往父类找。

Spring编程式事务管理中,当出现异常时事务未正确回滚的问题通常与Spring事务传播机制和异常处理方式有关。以下是几种常见的解决方案: ### 1. 使用 `TransactionTemplate` 进行编程式事务管理 Spring 提供了 `TransactionTemplate` 类来实现编程式事务控制。通过 `TransactionCallback` 接口执行事务性操作,并可以在发生异常时手动触发回滚。 ```java @Autowired private TransactionTemplate transactionTemplate; public void performTransactionalOperation() { transactionTemplate.execute(status -> { try { // 执行数据库操作 someDatabaseOperation(); } catch (Exception e) { // 发生异常时手动标记事务回滚状态 status.setRollbackOnly(); throw new RuntimeException("Transaction rolled back due to exception", e); } return null; }); } ``` 使用 `TransactionTemplate` 可以更细粒度地控制事务边界,并且在捕获异常后通过调用 `setRollbackOnly()` 方法确保事务回滚 [^3]。 --- ### 2. 在捕获异常后抛出运行时异常 Spring 默认只在方法抛出 `RuntimeException` 或其子类时才会自动回滚事务。因此,在 `try-catch` 中捕获异常后,应重新抛出一个运行时异常以触发事务回滚机制。 ```java @Transactional public void businessMethod() { try { // 数据库操作 someDatabaseOperation(); } catch (Exception e) { // 抛出运行时异常以触发事务回滚 throw new RuntimeException("Operation failed, rolling back", e); } } ``` 这种方式适用于声明式事务管理,但也可以结合编程式事务使用 [^2]。 --- ### 3. 手动调用 `TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()` 如果希望在抛出异常的情况下仍然回滚事务(例如日志记录、补偿逻辑等),可以使用以下方式手动设置事务回滚标志: ```java @Transactional public void businessMethod() { try { // 数据库操作 someDatabaseOperation(); } catch (Exception e) { // 手动标记当前事务回滚状态 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 记录日志或执行其他补偿操作 log.error("Error occurred, transaction will be rolled back", e); } } ``` 该方法允许开发者在异常被捕获的情况下仍能控制事务回滚行为 [^1]。 --- ### 4. 确保事务边界清晰,避免内部方法调用导致失效 在同一个类中,若非事务方法调用了带有 `@Tranctional` 注解的方法,则事务不会生效。这是由于 Spring AOP 的代理机制限制。可以通过注入自身 Bean 来绕过这一问题: ```java @Component public class MyService { @Autowired private MyService selfProxy; public void outerMethod() { selfProxy.innerTransactionalMethod(); // 调用代理对象,事务生效 } @Transactional public void innerTransactionalMethod() { // 事务性操作 } } ``` 此方式适用于混合使用声明式与编程式事务的情况 [^4]。 --- ### 总结 | 方案 | 适用场景 | 特点 | |------|----------|------| | `TransactionTemplate` | 编程式事务控制 | 更灵活,适合复杂事务逻辑 | | 抛出运行时异常 | 声明式事务管理 | 简单有效,但需注意异常类型 | | 手动设置回滚标志 | 异常处理后仍需回滚 | 抛出异常也能回滚 | | 自身注入解决代理失效 | 同一类中调用事务方法 | 避免AOP代理失效问题 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值