我使用spring(1.4.1)和hibernate(5.0.1.Final)。我注意到,当我试图从@TransactionalEventListener处理程序中写入数据库时,调用就被忽略了。打电话就行了。当我说“忽略”时,我的意思是数据库中没有写,也没有日志。我甚至启用了log4jdbc,但仍然没有日志,这意味着没有创建hibernate会话。由此,我估计,在spring引导的某个地方,我们发现它是一个事务事件处理程序,而忽略了一个写调用。
下面是一个例子。
// This function is defined in a class marked with @Service
@TransactionalEventListener
open fun handleEnqueue(event: EnqueueEvent) {
// some code to obtain encodeJobId
this.uploadService.saveUploadEntity(uploadEntity, encodeJobId)
}
@Service
@Transactional
class UploadService {
//.....code
open fun saveUploadEntity(uploadEntity: UploadEntity, encodeJobId: String): UploadEntity {
// some code
return this.save(uploadEntity)
}
}现在,如果我通过注释强制执行一个新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
saveUploadEntity 一个有连接的新事务被完成,一切都很好。
此外,启用成功记录读写的log4jdbc,我在春季有以下设置。
谢谢
发布于 2017-11-20 08:18:24
我也遇到了同样的问题。TransactionSynchronization#afterCompletion(int)的文档中实际上提到了这种行为,TransactionPhase.AFTER_COMMIT引用了这种行为(它是@TransactionalEventListener的默认TransactionPhase属性):
事务已经提交或回滚,但是事务性资源可能仍然是活动的和可访问的。因此,此时触发的任何数据访问代码仍将“参与”原始事务,允许执行一些清理(不再有提交跟踪!),除非它明确声明需要在单独的事务中运行。因此:对从这里调用的任何事务操作都使用PROPAGATION_REQUIRES_NEW。
不幸的是,这似乎只剩下通过Propagation.REQUIRES_NEW强制执行新事务的选项了。问题是,transactionalEventListeners是作为事务同步实现的,因此绑定到事务。当事务关闭并清理其资源时,侦听器也是如此。可能有一种方法可以使用自定义的EntityManager,它存储事件,然后在调用close()之后发布它们。
请注意,您可以在@TransactionalEventListener上使用TransactionPhase.BEFORE_COMMIT,这将在事务提交之前进行。这将将您的更改写入数据库,但您将不知道您正在侦听的事务是实际提交的还是即将回滚的。
https://stackoverflow.com/questions/43725538
复制相似问题