![](/img/trans.png)
[英]Transactional method called by method in same class called from another class
[英]@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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.