【问题标题】:Java Batch Transaction ControlJava 批处理事务控制
【发布时间】:2021-03-02 05:28:26
【问题描述】:

我有一些用于运行 bean 托管事务的代码(我的代码将处理何时启动或提交事务)。此代码已迁移到容器管理的事务中,最后在 Java Batch 中使用(Wildfly 中的 JSR-352)。

现在我们处理的数据量增加了,我们看到了与事务相关的问题。在各种情况下,甚至查询都会失败,并且异常表明事务被标记为仅回滚。所以我认为之前的迁移过程中一定发生了一些错误。

我仍然想使用容器管理的事务,但是...

  • 如何在 batchlet 中正确使用 CDI 以便它接收 EntityManager?我是使用@PersistenceContext、@PersistenceUnit 还是@Inject 注释,还是组合使用?
  • 如何使用合理的 CDI 范围?查看https://github.com/jberet/jberet-user-guide/blob/master/custom_cdi_scopes/README.md 会出现三个范围:作业、步骤和分区。由于我运行了太长时间的批处理,我可能需要分区范围,但是批处理如何控制分区?
  • 我了解到读取器/处理器/写入器模式控制事务 ootb 以获取大量记录。该模式是否适用于读取记录、对其进行处理然后立即更新或删除它的代码?

【问题讨论】:

    标签: transactions cdi jberet


    【解决方案1】:

    同时我发现了这个问题,并且与我发布一个模糊的问题类似,我现在可以看到我的问题的答案并不容易得出结论。

    我的代码过去常常在没有容器的情况下运行,所以显然它自己管理它的事务。后来添加了一个容器,最终我开始编写使用容器管理事务的代码。但是只有一个持久性单元,它被配置为容器管理的事务。在数据集增长之前,这似乎在很长一段时间内都没有问题。

    对我来说,解决方案是拥有两个持久性单元——一个有容器管理的事务,一个没有容器管理的事务:一个是本地资源,另一个是 JTA。 我的代码需要使用正确的持久性单元,以便正确管理事务。

    【讨论】:

    • 没错。 JPA 规范在明确表明存在两种“模式”方面一直做得很差:“应用程序模式”JPA(您在其中调用 Persistence#createEntityManagerFactory() 之类的东西并管理您自己的事务,以及“容器模式”JPA(非常一旦您通过@PersistenceContext 注入EntityManager,就会应用特定的交易相关规则。
    【解决方案2】:

    您可以查看WildFly Quickstart for batch processing,其中包含一些混合批处理、CDI 和 JPA 的有用示例,包括使用@Inject 注入持久上下文。

    对于使用 JBeret 的各种 CDI 范围,这取决于您的特定用例。对于大多数批处理应用程序,他们可能不需要担心它。但如果您确实发现自己需要控制某些 CDI bean 的范围,那么请选择最适合 bean 预期生命周期的范围。

    如果你想在你的项目编写器中立即更新或删除它,你当然可以选择item-count of 1。这是可行的,但效率会降低。

    【讨论】:

    • 感谢您的建议。这次探针根本不在 JBatch 上,因为我的 batchlet 很好地控制了事务。然而,持久化单元是为 JTA 配置的,这意味着容器也试图控制事务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2018-07-28
    • 2014-05-15
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多