【问题标题】:transaction-type="RESOURCE_LOCAL with jta-data-sourcetransaction-type="RESOURCE_LOCAL 与 jta-data-source
【发布时间】:2021-08-16 19:51:33
【问题描述】:

我遇到了一个使用 OpenJPA 和 DB2 在 Websphere Liberty 18 上运行的旧项目。在 persistence.xml 文件中有一个具有以下声明的持久单元:

<persistence-unit name="my-pu" transaction-type="RESOURCE_LOCAL">       
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/my-data-source</jta-data-source>
</persistence-unit>

如果我们使用 RESOURCE_LOCAL 事务并且有代码可以手动管理分散在整个应用程序中的事务,那么数据源不应该声明为“non-jta-data-资源”?有趣的是,尽管如此,该应用程序似乎运行良好。任何想法为什么它可以正常工作?

【问题讨论】:

  • 为什么它不能工作? jta-data-source 应该指向 JTA-aware 数据源,如果使用它,事务类型默认设置为 JTA,但由于您明确要求使用 RESOURCE_LOCAL 事务相反,没有什么特别的事情发生

标签: jpa db2 websphere-liberty openjpa open-liberty


【解决方案1】:

&lt;non-jta-data-source&gt; 指定拒绝加入 JTA 事务的数据源。这意味着,如果您执行 userTransaction.begin(或利用容器为您启动事务的任何 API),并且您对数据源(在 Liberty 中标记为 transactional="false")执行一些操作,那么操作不会成为包含 JTA 事务的一部分,并且可以独立提交或回滚。这绝对是一种高级模式,如果您不知道自己在做什么,或者暂时忘记数据源未登记,您最终可能会编写损坏数据的代码。此时,您可能想知道为什么 JPA 甚至有这样的选项。我希望它根本不适合最终用户使用 JPA 编程模型,而是真正用于 JPA 持久性提供程序(Hibernate/EclipseLink/OpenJPA)实现。例如,如果您考虑 JTA 事务在线程上处于活动状态并通过 JPA 执行操作,其中 JPA 持久性提供程序需要为您生成唯一密钥,并且持久性提供程序需要运行一些数据库命令来保留下一个唯一键块,JPA 持久性提供程序不能只在您的事务中执行此操作,因为您最终可能会回滚它,然后可能会给出相同的唯一键块两次并且会发生错误。 JPA 持久性提供者确实需要暂停您的事务,运行它自己的事务,然后恢复您的事务。在我看来,暂停/恢复将是这里的自然解决方案,但 JTA 规范没有提供获取 TransactionManager 的标准方法,所以我的猜测是 JPA 规范为这种需要绕过事务登记作为替代的数据源。 JPA 提供者可以在非 jta 数据源上运行自己的事务操作,而您的 JTA 事务继续不受其影响。您还会注意到我选择的示例,它不适用于通过 JPA 的许多路径。如果您的 JPA 实体配置为让数据库生成唯一键,则持久性提供程序不需要在非 jta-data-source 上执行其自己的数据库操作。如果您不使用 JTA 事务,则持久性提供程序无需担心在您的事务中登记,因为它可以使用不同的连接,因此它也不需要非 jta-data-source。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    • 2015-02-23
    • 2011-05-02
    • 1970-01-01
    • 2010-12-30
    • 2014-11-11
    相关资源
    最近更新 更多