确保 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();
    }

    ...
}