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

der*_*itz 6 java jpa jpa-2.0

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

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

And*_*i I 9

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

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

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

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

find方法(假设它在没有锁的情况下调用或使用LockModeType.NONE调用)和getReference方法不需要在事务上下文中调用.如果正在使用具有事务范围持久性上下文的实体管理器,则将分离生成的实体; 如果使用具有扩展持久性上下文的实体管理器,则将对它们进行管理.有关实体经理在交易外使用的信息,请参阅第3.3节

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

对于问题的第二部分:如果您调用了托管实体的setter,并且没有刷新,则将其分离(即在事务提交之前),行为不明确/未定义,即您应该更好地更正代码.

有缺陷的代码示例:

//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
Run Code Online (Sandbox Code Playgroud)

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

  • 根据我的经验:虽然 JPA 规范需要一个事务,并说如果没有事务绑定到会话(对于那些提到的操作),应该抛出 TransactionRequiredException,但在资源本地实体管理器的情况下,没有抛出异常(例如它在 JAVA EE 上下文中是 Hibernate)。无论如何,你能发布一些你的代码吗?此外,当您更改数据时,真的建议在所有这些情况下使用事务。还可以尝试禁用持久性提供程序的自动提交模式(在您的情况下为 ElipseLink)以强制执行事务。 (2认同)