Transaction rolled back because it has been marked as rollback-only

绝地灬酷狼 2022-06-10 06:20 211阅读 0赞

Transaction rolled back because it has been marked as rollback-only

spring 具备多种事务传播机制,最常用的是REQUIRED,即如果不存在事务,则新建一个事务;如果存在事务,则加入现存的事务中。
示例代码如下:

  1. public void A() {
  2. querySomething(...);
  3. try {
  4. B()
  5. } catch () {
  6. }
  7. saveSomethinf();
  8. }
  9. public void B() {
  10. throw Exception()
  11. }

此时B会和A存在一个事务中。如果B抛出异常没有捕获,即使在A中捕获并处理,仍会发生异常:Transaction rolled back because it has been marked as rollback-only
因为spring会在A捕获异常之前提前捕获到异常,并将当前事务设置为rollback-only,而A觉得对异常进行了捕获,它仍然继续commit,当TransactionManager发现状态为设置为rollback-only时,
则会抛出UnexpectedRollbackException
相关代码在AbstractPlatformTransactonManager.java中:

  1. public final void commit(TransactionStatus status) throws TransactionException {
  2. if (status.isCompleted()) {
  3. throw new IllegalTransactionStateException(
  4. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  5. }
  6. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  7. if (defStatus.isLocalRollbackOnly()) {
  8. if (defStatus.isDebug()) {
  9. logger.debug("Transactional code has requested rollback");
  10. }
  11. processRollback(defStatus);
  12. return;
  13. }
  14. if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
  15. if (defStatus.isDebug()) {
  16. logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
  17. }
  18. processRollback(defStatus);
  19. // Throw UnexpectedRollbackException only at outermost transaction boundary
  20. // or if explicitly asked to.
  21. if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
  22. throw new UnexpectedRollbackException(
  23. "Transaction rolled back because it has been marked as rollback-only");
  24. }
  25. return;
  26. }
  27. processCommit(defStatus);
  28. }

解决方法:
在抛出异常的最原始地方处理异常,即在spring捕获到异常之前处理掉

转载地址:https://github.com/willdonggg/tech-blog/blob/master/Transaction%20rolled%20back%20because%20it%20has%20been%20marked%20as%20rollback-only.md

发表评论

表情:
评论列表 (有 0 条评论,211人围观)

还没有评论,来说两句吧...

相关阅读