java - Spring 在@Transactional 方法中捕获 JpaSystemException 并回滚事务
问题描述
我有一个带有注释的方法
@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
并调用几个存储库方法。现在,当一个存储库尝试更改已锁定且未被该方法的另一个实例回滚的 DB 行时,spring 会正确抛出
org.springframework.orm.jpa.JpaSystemException: could not execute statement [...] Caused by: java.sql.SQLException: transaction could not be serialized and rolls back the failed transaction.
现在我想保留所有这些行为,但另外处理异常并开始重试。这是一个代码片段:
@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@Lock(LockModeType.PESSIMISTIC_WRITE)
public void messageReceived(Card card) {
this.request = request;
this.numberOfAttempts = reset ? 0 : this.numberOfAttempts++;
this.reset = true;
LOGGER.info("Message received from Queue: " + card);
TransactionDebugUtils.transactionRequired("MessageReceivedController.messageReceived");
try {
[...]
repository1.createKonto(card);
repository2.doStuff(card);
} catch (JpaSystemException e) {
//This is obviously never invoked
LOGGER.error("TRANSACTION FAILED!!!");
} catch (Exception e) {
LOGGER.error("Error mapping json request to data model", message, e);
}
}
@ExceptionHandler(JpaSystemException.class)
//This is also never invoked
public void handleJpaSystemException(JpaSystemException ex) {
this.messageReceived(this.request);
this.reset = false;
}
解决方案
我最近有这个问题。由于它是一个方法级别的@Transactional 注解,所以事务提交是在方法执行完成之后发生的。当您使用此注释时,应考虑 2 个概念
- 持久性上下文
- 数据库事务
执行 messageReceived() 方法后,将发生这两件事,并且在 @Transactional 级别引发 JPA 异常,这意味着您需要从调用此方法的位置处理此异常(控制器;如果您从控制器调用)。更多关于 @Transactional 的信息可以在这个链接中找到。
推荐阅读
- javascript - Angular Ionic 4 如何将变量从 page.html 传递到 page.ts
- amazon-cognito - 使用 SAML 2 更新令牌问题的 Okta 作为 IdP 的 Cognito
- owl - 是否有“标记”OWL 类的程序?
- linux-kernel - 在 BeagleBone 上引导 Linux 内核时挂载 NFS
- vega - 是否可以根据周期时间列显示 vega/vega-lite 条?
- r - R:有没有办法搜索几乎相同的行?
- r - quantregForest 播种
- ios - 循环数组并使其为空。为什么它表现得很奇怪?
- angular - 使用 forRoot 的默认值配置在 Dev 中有效,但在 Prod (Aot) 中无效
- android - 如何在 Kotlin 中更新条目 Firebase 实时数据库 - 代码