spring @transactional事务问题及解决

 

1. 数据库引擎选择错误

2.@transactional标注的方法 所在的类需要被spring管理 并且方法是public修饰

3. 自调用的时候出现的事务失效:

复制代码
 1 @Service
 2 public class Service{
 3     
 4     public void m(){
 5         m1();
 6         m2();
 7 
 8     }
 9 
10     @transactional
11     public void m1(){
12 
13     
14     }
15     @transactional
16     public void m2(){
17 
18     }
19 }    
复制代码
复制代码
 1 @Service
 2 public class DmzService {
 3     @Transactional
 4     public void save(A a, B b) {
 5         saveB(b);
 6     }
 7     
 8     @Transactional(propagation = Propagation.REQUIRES_NEW)
 9     public void saveB(B b){
10         dao.saveB(b);
11     }
12 }
复制代码

以上两种情况皆会导致事务失败,原因是 自调用调用的是目标类而不是代理类的方法,所以解决问题的点也在这里

使用代理类的方法是

1. 自己autowire注入自己

2. 使用aopcontext

复制代码
@Service
public class DmzService {

    @Transactional
    public void save(A a, B b) {
        ((DmzService) AopContext.currentProxy()).saveB(b);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveB(B b){
        dao.saveB(b);
    }
}

// exposeProxy=true代表将代理类放入到线程上下文中,默认是false
@EnableAspectJAutoProxy(exposeProxy = true)

复制代码

事务回滚问题

  1. 想回滚却提交了

  spring默认回滚是发生了error或者RunTimeException 如果想要回滚其他的异常 需要制定rollbackfor

  2. 想提交却回滚了

  

复制代码
@Service
public class DmzService {

    @Autowired
    IndexService indexService;

    @Transactional
    public void testRollbackOnly() {
        try {
            indexService.a();
        } catch (ClassNotFoundException e) {
            System.out.println("catch");
        }
    }
}

@Service
public class IndexService {
    @Transactional(rollbackFor = Exception.class)
    public void a() throws ClassNotFoundException{
        // ......
        throw new ClassNotFoundException();
    }
}
复制代码

以上代码会抛出异常! 原因是 事务嵌套的情况下,当内部事务回滚会把rollbackOnly属性设置为true 所以会回滚

解决:

  1. 如果想内部事务回滚 外部事务继续执行

    将内部事务的传播级别设置为nested或者requires_new 

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)

  2. 想内部事务发生异常 外部事务回滚 整体回滚 不抛异常

复制代码
@Transactional
public void testRollbackOnly() {
try {
   indexService.a();
} catch (ClassNotFoundException e) {
   // 加上这句代码
   TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
}
}
复制代码

 

posted @   rudynan  阅读(354)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示