应用程序管理JPA,何时需要Transaction

时间:2014-02-10 08:45:32

标签: java jpa jpa-2.0

我们正在开发一个小网站(将在Tomcat上运行),数据层使用JPA(Eclipselink)完成。 我前段时间做过类似的事情。但我总是不确定何时需要开始和结束交易或进行同花。 目前我使用事务,如果我添加(持久)和删除对象。如果我在已经存在的对象上调用setter,我就不使用事务。

在使用事务或如何正确实现应用程序管理的JPA时,是否有指南/教程或简短答案。

1 个答案:

答案 0 :(得分:9)

我认为可以总结一个问题的答案。 几乎所有JPA操作都需要一个事务,除了不锁定实体的查找/选择(即任何不改变数据的JPA操作)。

(JTA事务范围实体管理器) 对于JTA事务范围的实体管理器,最好引用规范(第3章实体操作):

  

必须在其中调用persist,merge,remove和refresh方法   具有a的实体管理器的事务上下文   使用事务范围的持久性上下文。   如果没有事务上下文,则抛出javax.persistence.TransactionRequiredException。

     

必须调用指定LockModeType.NONE以外的锁定模式的方法   在事务上下文中。   如果没有事务上下文,则抛出javax.persistence.TransactionRequiredException。

     

find方法(前提是它在没有锁定的情况下调用或使用   LockModeType.NONE)和getReference方法不是必需的   在事务上下文中调用。如果是实体经理   事务范围的持久化上下文正在使用中,由此产生   实体将被分离;如果实体经理有扩展   使用持久化上下文,它们将被管理。见3.3节   实体经理在交易之外使用。

(应用程序管理/资源本地实体管理器) 对于应用程序管理的实体管理器,JPA规范不清楚该行为。在Hibernate的情况下,当不在事务内部时(它也可能依赖于JDBC驱动程序和DB连接的自动提交模式),发生的事情非常复杂。检查此主题的Hibernate's article基本上,我们强烈建议您始终将交易用于上述操作。

到你问题的第二部分:如果你调用了一个托管实体的setter,并且没有刷新你分离它(即在事务提交之前),行为是不明确/未定义的,即你应该更好地纠正代码。 / p>

错误代码示例:

//begin Transaction
MyEntity entity = em.find(MyEntity.class, 1L);
entity.setField("New value");
em.detach();//it is not sure whether the "New value" will be persisted. To make sure it is persisted, ypu need to call em.flush() before detaching
//commit Transaction

通常,如果DB操作的顺序(与enity manager操作的顺序不同)不重要,您可以让JPA实现决定何时刷新(例如,在事务提交时)