关于Spring的隔离级别和传播

发布于 2022-09-11 22:43:39 字数 846 浏览 20 评论 0

下面代码中,我想要先在f1中从表table_apple读一些记录,然后在f2中更新table_apple其中某些记录,然后在f1中从表table_apple读出f2更新后的记录,所以要用Isolation.READ_COMMITTED覆盖掉mysql默认的REPEATABLE隔离级别
另外又不想让f1()抛异常导致f2被回滚,所以用propogation= Propogation.REQUIRES_NEW

 @Transactional(isolation= Isolation.READ_COMMITTED)
 void f1(){
      select from table_apple;
      f2();
      select from table_apple;
      throw new RuntimeException()
 }
 
 
 @Transactional(propogation= Propogation.REQUIRES_NEW, isolation= Isolation.REPEATABLE_READ)
 void f2(){
      update table_apple;
 }
 
 

我想问的是,我这样用会达到目标吗?另外,我在f2中显示写出了isolation= Isolation.REPEATABLE_READ,事实上默认就是这个级别,所以写不写一样,我想问的是,假如内层方法没有用propogation= Propogation.REQUIRES_NEW,则和外层方法属于同一个事务,但是如果标注了不同的隔离级别,那么是外层方法的隔离级别覆盖所有内层方法@Transactional上标注的隔离级别吗?


补充,看了@znydev的回答,我疏忽了,我要问的是假如两个方法在不同的类中或者f1用所在类代理类调用f2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2022-09-18 22:43:39

看你上面的问题,下面的回答有个前提,就是 f1 和 f2 在同一个类里面

首先回答一下主要问题,你这样做不能达到目标,这些操作会在同一个事务中进行,而不是 f2 新开一个事务

简单说下原因:Spring 的事务使用的 AOP 实现的,你这样做的代码,可以看成下面的形式


class Demo { 
    @Transactional(isolation= Isolation.READ_COMMITTED)
    void f1(){
        select from table_apple;
        this.f2();
        select from table_apple;
        throw new RuntimeException()
    }
 
 
    @Transactional(propogation= Propogation.REQUIRES_NEW)
    void f2(){
      update table_apple;
    }
}

其中 如果 f1 调用 f2 使用的是 this 而不是代理类,所以 f2 只是一个普通方法,事务注解并不会生效,你可以将这两个方法放在两个类中,如


class Demo2 {
     
    @Transactional(propogation= Propogation.REQUIRES_NEW)
    void f2(){
      update table_apple;
    }
}

class Demo {

    private Demo2 demo2;
 
    @Transactional(isolation= Isolation.READ_COMMITTED)
    void f1(){
        select from table_apple;
        demo2.f2();
        select from table_apple;
        throw new RuntimeException()
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文