[英]Spring @Transactional different behavior on Service and non-Service methods?
我有一个具有标准架构(控制器 -> 服务 -> 存储库)的 Spring Boot 2.3 REST 应用程序。 出于审计目的,我插入了一个薄层(某种Mediator ),以便我将所有请求持久化到某个特定的服务方法,无论它们是成功持久化还是抛出异常并回滚事务。 例子:
@Component
public class Mediator {
private final Service service;
private final AuditService auditService;
public Mediator(Service service, AuditService auditService) {
this.service = service;
this.auditService = auditService;
}
@Transactional
public void saveReport(Report report) {
try {
service.saveReport(report);
auditService.saveReport(report);
} catch (Exception exception) {
auditService.saveReport(report, exception);
throw exception;
}
}
}
于是我遇到了一个奇怪的情况:如果我把@Transactional
放在Mediator 的方法上(上面的例子),JPA Repositories 中的所有操作都成功持久化了。 如果我将@Transactional
放在 ServiceImpl 方法上(下面的示例)并且不再放在 Mediator 上,则不会运行其中一个删除查询,尽管其余查询执行得很好。 假设我的 ServiceImpl 看起来像:
@Service
public class ServiceImpl implements Service {
private final RepositoryA repositoryA;
private final RepositoryB repositoryB;
public ServiceImpl(RepositoryA repositoryA, RepositoryB repositoryB) {
this.repositoryA = repositoryA;
this.repositoryB = repositoryB;
}
@Transactional
public void saveReport(Report report) {
repositoryA.save(report.getA());
repositoryB.save(report.getB());
repositoryB.delete(report.getSomethingElse());
}
}
关于事务的两种方法之间唯一明显的区别是,在第一个场景中,我对每个 Mediator 调用都有这个:
o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [SessionImpl(909894553<open>)] for JPA transaction
在第二种情况下,我有这个:
tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
我想直接用@Transactional
注释 bean 的方法(我在 Mediator 中所做的)和用相同的东西注释 bean 的(即接口注入的实现)方法(我们通常通过注释一个ServiceImpl 方法),但我不确定也无法找出这种奇怪行为的原因。 有谁知道为什么会发生这种情况?
我想这种行为差异是由于 Spring OpenSessionInView 默认启用的。 您必须在 application.yml 中设置
spring:
jpa:
open-in-view: false
请参阅OSIV
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.