【问题标题】:Making sure JPA commits my transaction before another service accesses the data确保 JPA 在其他服务访问数据之前提交我的事务
【发布时间】:2015-05-22 20:20:40
【问题描述】:

感觉很简单:

我有一个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() 的末尾强制提交事务,但这感觉非常肮脏和危险。

另一种选择是关闭整个项目的容器管理事务,但这意味着我必须让我的 所有 bean 手动管理它们的事务,只是 em> 这样我就可以解决这个问题了。

有没有更好的办法?

【问题讨论】:

  • 等等,您的 JSF 托管 bean 是事务性的..?这不是默认行为。你们的 JSF 支持 bean 类都有哪些注释?您应该基本上将事务方法分离到一个真正的服务类中,然后将其注入到您的 JSF 托管 bean 中。
  • 仅限javax.faces.bean.ViewScoped
  • @BalusC - 显然,everything 我的网络应用确实打开了一个事务。我打开了com.arjuna.ats.jta 的跟踪日志记录,我得到了一些事务,比如从服务器请求一个静态PNG,甚至只在一个既不接触EntityManager 也不接触数据库的bean 中运行@Schedule(...) 方法。有些东西配置错误,这似乎很清楚。我什至从哪里开始寻找?
  • “我什至从哪里开始寻找?” 您的 web.xml 中的 servletfilters?
  • @Kukeltje - 谢谢,我也是这么想的,确实有两三个。但是它们都没有任何事务性内容或注释。 不过,我找到了罪魁祸首。 我们的项目是一个奇怪的混蛋,它使用 EE6 和 Seam 来获取 @ViewScoped bean。作为 Seam 的一部分,org.jboss.seam.transaction 中的依赖关系 seam-transaction。一旦进入,每个呼叫都会触发BaseTransaction.begin。我看看能不能摆脱它。

标签: jpa jsf-2 transactions jta


【解决方案1】:

回答我自己的问题:

我只去了一半,这就是为什么它不起作用。我对 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();
    }

    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2011-03-13
    相关资源
    最近更新 更多