[英]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.