# org.springframework.transaction.TransactionSystemException：无法提交JPA事务；嵌套异常为javax.persistence.RollbackException：事务已回滚，因为它被标记为仅回滚

- **ID:** `java/transaction-rolled-back-deadlock`
- **领域:** java
- **类别:** runtime_error
- **验证级别:** ai_generated
- **修复率:** 85%

## 根因

当事务被标记为仅回滚（例如由于数据完整性违规或乐观锁定失败），但外部事务上下文尝试提交它时发生，通常在嵌套事务或服务层中捕获并吞没了异常。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| Spring Boot 2.7.x | active | — | — |
| Spring Boot 3.2.x | active | — | — |
| Hibernate 5.6.x | active | — | — |
| Hibernate 6.3.x | active | — | — |

## 解决方案

1. ```
   Use REQUIRES_NEW propagation for the inner method to create a separate transaction: `@Transactional(propagation = Propagation.REQUIRES_NEW)` so that the inner transaction's rollback does not affect the outer transaction.
   ```
2. ```
   Check for rollback-only status before committing: `TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();` and then handle the error gracefully in the outer method by calling `TransactionAspectSupport.currentTransactionStatus().flush()`.
   ```
3. ```
   Refactor the code to avoid swallowing exceptions: ensure that any exception that triggers a rollback is rethrown to the outer transactional boundary, e.g., `catch (DataIntegrityViolationException e) { throw new RuntimeException(e); }`.
   ```

## 无效尝试

- **Adding @Transactional(rollbackFor = Exception.class) to all methods** — This does not prevent the rollback-only marking; it only ensures exceptions trigger rollback. The issue is that an exception was caught and the transaction was marked rollback-only, then a commit is attempted. (80% 失败率)
- **Catching the exception in the outer method and ignoring it** — The transaction is already marked rollback-only by the inner method; ignoring the exception does not reset the transaction status. (90% 失败率)
- **Increasing the transaction timeout to avoid premature rollback** — The rollback is due to a data error (e.g., constraint violation), not a timeout. Increasing timeout does not address the root cause. (70% 失败率)
