我有一个小型 Spring Boot 应用程序,其中包含
spring-boot-starter-web
、spring-boot-starter-data-jpa
和 postgresql
作为依赖项。
我能够使用
@Transactional
注释并使用 JPA 来获取实体并将其保存到数据库中。但是,如果我通过注册同步来添加 afterCommit
/afterCompletion
钩子,它会给出一个 IllegalStateException
表示 Transaction synchronization is not active
。
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
//this doesn't get called
log.info("do something here");
}
});
执行
TransactionSynchronizationManager.initSynchronization();
可以消除错误,但不会调用挂钩(例如:即使事务已提交,也不会调用 afterCommit
挂钩。)
有关如何调试此问题的任何线索?
事实证明,我忘记包含用于为具有 @Transactional 注释的 bean 创建 AoP 代理的构建插件。
如果没有这个插件,就不会生成任何代理,并且代码将以非事务方式运行;除了当它进入
JpaRepository
方法时,它将在调用期间创建一个短期事务(例如 save
/findAll
/delete
)。
这是我错过的包含在我的 pom.xml 中的插件(它是由 Spring Initializr 在 pom 输出中生成的(https://start.spring.io/),但我一开始没有注意到它,没有将其复制到我的 pom 中)
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我认为你需要
@TransactionalEventListener
注释。它支持钩子 BEFORE_COMMIT、AFTER_ROLLBACK、AFTER_COMPLETION、AFTER_COMMIT 和 AFTER_ROLLBACK。
本文中的更多信息:Spring Framework 4.2 中更好的应用程序事件。
交易开始后TransactionManager正在清除 同步收集,您应该在事务开始后执行此操作。