同一個類中@Transactional 事務失效

1.在同一個類中一個沒有事務 A 的方法調用另個有事務 B 的方法,那麼那個有事務 B 的方法是失效的;

public class test {

    public void a() { 
        this.b();
    }

    @Transactional
    public void b() {
        /* … */
    }
}

2.如果有事務 A 方法調用沒有(或者有)事務 B 的方法,那麼事務 A 都會生效,而方法 B 不會生效;

public class test {

    @Transactional
    public void a() { 
        this.b();
    }

    @Transactional
    // @Transactional
    public void b() {
        /* … */
    }
}

3.但是如果是不同類的話就都會生效;

總結 

我們調用的方法A不帶註解,因此代理類不開事務,而是直接調用目標對象的方法。當進入目標對象的方法後,執行的上下文已經變成目標對象本身了,因爲目標對象的代碼是我們自己寫的,和事務沒有半毛錢關係,此時你再調用帶註解的方法,照樣沒有事務,只是一個普通的方法調用而已。簡單來說,內部調用本類方法,不會再走代理了,所以B的事務不起作用

解決方案:

  1. 可以將方法放入另一個類,並且該類通過spring注入,即符合了在對象之間調用的條件。
  2. 獲取本對象的代理對象,再進行調用。具體操作如:
    1)Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy=“true”/>
    2)在xxxServiceImpl中,用(xxxService)(AopContext.currentProxy()),獲取到xxxService的代理類,再調用事務方法,強行經過代理類,激活事務切面。
    public class test {
    
        @Transactional
        public void a() { 
            (test)(AopContext.currentProxy()).b();
        }
    
        @Transactional
        // @Transactional
        public void b() {
            /* … */
        }
    }
  3. 當然也可以@Autowired 注入自己來調用方法解決。
  4. 把註解加到類名上面。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章