持久化单元应该选择RESOURCE_LOCAL还是JTA?

103

我有以下查询:

  1. 这两者有什么区别?
  2. 所有数据库都支持这两个吗?
  3. JPA TransactionManager 和 JTA TransactionManager 有什么不同?
4个回答

108

JPA实现可以选择自己管理事务(RESOURCE_LOCAL),或者让应用服务器的JTA实现来管理事务。

在大多数情况下,使用RESOURCE_LOCAL就可以了。这会使用基本的JDBC级别事务。缺点是事务局限于JPA持久单元本身,因此如果您需要跨多个持久单元(或其他数据库)的事务,则RESOURCE_LOCAL可能不够好。

JTA也用于管理跨JMS和JCA等系统的事务,但对于我们大多数人来说,这是相当奇特的用法。

要使用JTA,您需要在应用服务器中获得支持,并且还需要从JDBC驱动程序获得支持。


3
似乎GlassFish不允许我使用resource_local - 我该怎么做? - Pete_ch
3
作为一则旁注:即使没有完整的Java EE应用服务器,仍然可以通过使用第三方解决方案(例如Atomikos)来获得JTA功能。因此,您可以使用轻量级的Web容器(例如Tomcat),仍然获得JTA支持。 - informatik01

98
作为对其他答案的补充,
以下是一篇非常有用的文章(发布在Apache TomEE网站上)的摘录,也可以帮助回答OP的第一个问题(文章链接在下面)。

比较RESOURCE_LOCAL和JTA持久性上下文
使用,您负责创建和跟踪EntityManager(PersistenceContext/Cache)...
您必须使用EntityManagerFactory来获取EntityManager 生成的EntityManager实例是一个PersistenceContext/Cache 只能通过@PersistenceUnit注释注入EntityManagerFactory(而不是@PersistenceContext) 不允许使用@PersistenceContext引用类型为RESOURCE_LOCAL的单元 必须在每个对EntityManger的调用周围使用EntityTransaction API进行开始/提交 两次调用entityManagerFactory.createEntityManager()会生成两个独立的EntityManager实例,因此有两个独立的PersistenceContexts/Caches。 几乎永远不要使用多个EntityManager实例(除非您已经销毁了第一个)
使用,容器将创建并跟踪EntityManager(PersistenceContext/Cache)...
无法使用EntityManagerFactory获取EntityManager 只能获取由容器提供的EntityManager 只能通过@PersistenceContext注释注入EntityManager(而不是@PersistenceUnit) 不允许使用@PersistenceUnit引用类型为JTA的单元 容器提供的EntityManager是与JTA事务关联的PersistenceContext/Cache的引用。 如果没有JTA事务正在进行,则无法使用EntityManager,因为没有PersistenceContext/Cache。 拥有指向同一单元中的同一事务的EntityManager引用的所有人将自动引用相同的PersistenceContext/Cache。 在JTA提交时刷新和清除PersistenceContext/Cache。

如果你对学习Java持久化API感兴趣,请务必阅读完整的文章:JPA概念:JPA 101


11
想要补充一点:如果你在使用Spring,你可以使用@PersistenceContext和EntityManager与Resource_Local。在这种情况下,Spring容器可以使用@Transactional注解来管理事务。 - Sam
因为您提供的链接,我正在点击朝上的三角形。 - Koray Tugay
@KorayTugay 对不起,我没太明白你在说什么,是什么三角形? - informatik01
@informatik01 好的...我认为JTA有一些共同的规则,我想澄清一下。如果触发了flush,那么它会将数据发送到数据库,这是正确的吗?在我的情况下,当我触发flush时,一些更改被传播到数据库并且异常也发生了;之后我使用setRollbackOnly触发rollback,但是传播的更改仍然存在于数据库中。 - Radu Linu
1
@LinuRadu 这个回答可能对你有用:Hibernate 中 session.flush() 的作用是什么 - informatik01
显示剩余4条评论

19

Resource_Local和JTA是事务管理器(执行事务的方法),这不是数据库的属性,而是负责协调事务的组件。 JPA和JTA事务管理器是不同的。如果您只执行JPA事务,则JPA事务管理器负责JPA事务并且您需要使用它。而JTA事务管理器是通用事务管理器,可以在事务中列出其他资源,例如JMS队列。通常,Java EE容器为EJB、JPA实体等采用JTA事务管理器。


1

resource_local与JTA之间的区别是关于本地事务与全局事务。它涉及到我们是否可以在单个事务下管理多个资源。

CMT与BMT之间的区别是谁来开启和关闭事务 - 应用程序开发者还是应用服务器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接