JPA / @PostPersist @PostUpdate - 事务
Posted
技术标签:
【中文标题】JPA / @PostPersist @PostUpdate - 事务【英文标题】:JPA / @PostPersist @PostUpdate - transaction 【发布时间】:2011-06-21 05:14:23 【问题描述】:我目前正在使用@PostPersist
和@PostUpdate
,并且在这些触发器中我正在持久化其他实体。问题是,这些触发器是否在同一个事务中,如果不是,是否可以强制它?
对我来说,它是这样工作的。
当我查看日志时,事务不存在(它是在触发器启动之前提交的),这阻止了我(在注入 bean 的持久化方法上没有 REQUIRES_NEW
)将其他实体保存在数据库中。
REQUIRED
属性完全被忽略,MANDATORY
属性不抛出异常。
这可能是 JUnit 的问题吗(因为我处于开发阶段并且没有测试完整环境的行为。)?
如果无法在此触发器上扩展事务,如何确保回滚发生在@PostPersist
和@PostUpdate
之前,这些操作也会被回滚。
【问题讨论】:
嘿。当我进行测试时,我看到侦听器中的所有操作都在主操作的同一事务中。我使用@PostUpdate 注解来标记监听器。 【参考方案1】:如果您使用 Spring,您始终可以向当前事务管理器注册 TransactionSynchronization
,以便在事件(例如当前运行的事务的提交)时回调:
@PostPersist
void onPersist()
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter()
@Override
public void beforeCommit(boolean readOnly)
// do work
);
TransactionSynchronization
还在事务成功提交之后和事务完成之前/之后提供回调。
如果您需要检查事务是否已提交或回滚,请使用afterCompletion(int status)
。
详情请看TransactionSynchronization's JavaDoc。
【讨论】:
2021 年 7 月更新:TransactionSynchronizationAdapter 似乎已被弃用。您可以使用 TransactionSynchronization 接口来完成工作并摆脱弃用警告!【参考方案2】:PostPersist 事件的触发并不表示实体已成功提交。事务可以在事件触发之后但在成功提交之前回滚。 如果您在 PostPersist 中获取事务中使用的实体管理器,然后执行以下操作:
@PostPersist
void someMethod()
EntityManager em = null;
em = getEntityManagerUsedInTransaction();
EntityTransaction et = em.getTransaction(); // should return the current transaction
if (et.isActive() )
// do more db stuff
注意:我没有尝试过这个,所以这只是猜测(尽管我已经将生命周期事件触发器广泛用于其他东西)。 我必须补充一点,我认为这不是一个好主意。使用 PostPersist 标记其他实体应该被持久化并在另一个事务中执行。
【讨论】:
以上是关于JPA / @PostPersist @PostUpdate - 事务的主要内容,如果未能解决你的问题,请参考以下文章
Drupal 6.x中的hooku viewsu postu render
在wordpress中音译现有的西里尔语slug(postu name)