Play Framework - JPA - @Transactional error?

时间:2014-04-08 11:50:38

标签: jpa playframework-2.0 eclipselink transactional

我在使用带有JPA和Eclipse-Link的play-2.2.2进行交易时遇到了一种非常奇怪的行为。

我的Controller-Action使用@Transactional进行注释,如下所示:

@Transactional
public static Result submitOrder() {
// class does call private Methods which persist some entities (methods not annotated)
//...

Action正在调用私有方法来保存数据(这应该发生在同一个事务中,因为没有启动其他Transaction)。 在Methods调用期间(在随机位置),数据被写入db(插入和更新)。 Debuging显示在写入之前和之后使用相同(活动)事务。 EntityTransactionImpl:从未执行提交,并且事务在请求完成之前保持活动状态(观看play.db.jpa.JPA.em()。getTransaction()) 尽管事务仍然有效,但如何写入数据? 它破坏了setRollbackOnly机制,因为已经写入的数据没有被回滚。

可能有任何类型的超时发出这些写入。 你能否建议任何调试入口点来缩小问题范围(如果不是在EntityTransactionImpl:commit中,我可以在哪里开始调试实际的写操作)?

Dependencies in build.sbt

persistence.xml

1 个答案:

答案 0 :(得分:0)

上面描述的行为起初看起来很奇怪,但后来我读到了FlushMode,现在它有道理了。 eclipselink的FlushMode以及hibernate设置为FlushModeType.AUTO FlushModeType.AUTO在认为必要时自动将实体刷新到DB。这可能是因为对Persited(但没有刷新)实体的可读操作(Query),但在观察期间它也以某种方式随机发生。

这打破了故障回滚机制,我认为它必须是@Transactional的标准行为。

要在transcaction commit中的所有持久但未刷新的实体中执行propper rollback(在失败或设置了setRollbackOnly()时),您必须在Action的开头显式设置FlushMode。

JPA.em().setFlushMode(FlushModeType.COMMIT);

如果您正在使用Eclipselink,您还可以设置以下属性以使其成为默认行为:

<property name="eclipselink.persistence-context.flush-mode" value="commit" />

帮助我理解的链接:

Eclipselink Context Flushmode

what to use flush mode auto or commit

performance tuning hibernate