感觉很简单:
我有一个ViewScoped
bean(JPA2 + EE6 + Seam3,如果这很重要),Web应用程序的用户可以调用这样的方法:
public void save() {
doEntityManagerStuff(); // manipulates data in the database
callRemoteWebservice(); // which is to read said data and propagate it to other systems
}
不幸的是,save()
在开始大括号开始一个事务,而在结束括号之前没有提交它,这意味着远程Web服务无法使用新数据读取。
我试图明确地提取和注释数据库工作:
@TransactionAttribute(REQUIRES_NEW)
private void doEntityManagerStuff() {
blabla(); // database stuff
}
但这根本没有任何影响。 (也许是因为那是EJB的东西,而我正在接缝......?)
到目前为止,对我来说唯一有效的方法是注入@UserTransaction
并强制在save()
或doEntityManagerStuff()
结束时提交交易,但这感觉非常脏和危险。 / p>
另一种选择是关闭整个项目的容器管理事务,但这意味着我必须让所有我的bean手动管理他们的事务,只是所以我可以让这个案例有效。
有更好的方法吗?
答案 0 :(得分:0)
回答我自己的问题:
我只走了一半,这就是为什么它不起作用。我对EJB及其boudaries不太了解,虽然只是在我的视图范围的CDI / Seam bean中使用事务属性注释doEntityManagerStuff(...)
方法就足够了。
不是。
当我将所述方法移动到一个单独的无状态EJB 中时,将其注入我的CDI / Seam bean并从那里调用它,一切都按预期工作。
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyPersister {
...
public void doEntityManagerStuff() {
blabla(); // database stuff
}
...
}
和
@ViewScoped
public class MyWebsiteBean {
...
@Inject MyPersister persister;
...
public void save() {
persister.doEntityManagerStuff(); //uses its own transaction
callRemoteWebService();
}
...
}