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();
}
}
原文地址:https://www.cnblogs.com/isnotnull/p/14261319.html