确保 JPA 在另一个服务访问数据之前提交我的事务
Making sure JPA commits my transaction before another service accesses the data
感觉很简单:
我有一个 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()
结束时强制提交事务,但这感觉非常肮脏和危险.
另一种选择是关闭整个项目的容器管理事务,但这意味着我必须让 所有 我的 beans 手动管理它们的事务,只是 这样我就可以使这个案例有效。
有没有更好的方法?
回答我自己的问题:
我只进行了一半,所以没有成功。我对 EJB 及其边界知之甚少,天真地只是在我的视图范围 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();
}
...
}
感觉很简单:
我有一个 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()
结束时强制提交事务,但这感觉非常肮脏和危险.
另一种选择是关闭整个项目的容器管理事务,但这意味着我必须让 所有 我的 beans 手动管理它们的事务,只是 这样我就可以使这个案例有效。
有没有更好的方法?
回答我自己的问题:
我只进行了一半,所以没有成功。我对 EJB 及其边界知之甚少,天真地只是在我的视图范围 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();
}
...
}