簡體   English   中英

從另一個方法調用的@Transactional 方法不獲取事務

[英]@Transactional method called from another method doesn't obtain a transaction

在 Spring 中,如果沒有一個新事務,用@Transactional注釋的方法將獲取一個新事務,但我注意到如果從非事務方法調用事務方法,則不會獲取任何事務。 這是代碼。

@Component
public class FooDao {
    private EntityManager entityManager;

    @PersistenceContext
    protected void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    public Object save(Object bean) {
        return this.entityManager.merge(bean);
    }

    public Object saveWrap(Object bean) {
        return save(bean);
    }
}

@Component
public class FooService {
    private FooDao fooDao;

    public void save(Object bean) {
        this.fooDao.saveWrap(bean); // doesn't work.
        this.fooDao.save(bean); // works
    }
}

saveWrap()是調用save()的常規方法,它是事務性的,但saveWrap()不會保留任何更改。

我正在使用 Spring 3 和 Hibernate 3。我在這里做錯了什么? 謝謝。

這是 Springs AOP 的局限性之一。 因為dao bean在spring創建的時候其實就是一個proxy,也就是說從同一個類內部調用一個方法不會調用advice(也就是事務)。 任何其他切入點也是如此

是的,這是預期的行為。 @Transactional告訴 spring 在對象周圍創建一個代理。 代理攔截來自其他對象的對象調用。 代理不會攔截對象內的調用。

如果你想讓這個工作,在從“外部”調用的方法上添加@Transactional

我知道這有點晚了,但是我想添加一種克服此限制的方法,即在方法中從應用程序上下文中獲取 spring bean 並調用該方法。 當從應用程序上下文中獲取 spring bean 時,它將是代理 bean 而不是原始 bean。 由於代理 bean 現在正在調用方法而不是原始 bean,因此將在其上實現事務建議。

一種可能的解決方法是調用該方法,就像從“外部”調用它一樣

您可以通過獲取組件的當前代理然后調用方法來實現:

 ((MyService) AopContext.currentProxy()).innerMethod();

來源: https : //www.programmersought.com/article/58773839126/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM