捕获异常的情况下仍然回滚事务

在 MyBatis-Plus 和 Spring 的事务管理机制中,事务的回滚行为与异常的传播有很大关系。如果你捕获了异常并且没有将它重新抛出,那么事务是不会回滚的。

这是因为 @Transactional 注解默认只在未捕获的异常向上传播到 Spring 的事务管理器时,才会触发回滚。捕获异常后,Spring 不再认为这个操作是失败的,事务将正常提交。

示例

捕获异常且不回滚

如果你捕获了异常并且没有抛出它,事务不会回滚:

java 复制代码
@Transactional
public void someTransactionalMethod() {
    try {
        // 业务逻辑
    } catch (Exception e) {
        // 捕获异常,没有抛出
        // 此时事务不会回滚,除非手动调用 setRollbackOnly
    }
}
捕获后手动回滚

如果你需要在捕获异常的情况下仍然回滚事务,可以通过以下两种方式处理:

  1. 手动设置回滚 :通过 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 手动标记当前事务为回滚状态:

    java 复制代码
    @Transactional
    public void someTransactionalMethod() {
        try {
            // 业务逻辑
        } catch (Exception e) {
            // 捕获异常后,手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
  2. 重新抛出异常 :在捕获异常后将其重新抛出,让 @Transactional 注解感知异常,从而自动回滚事务:

    java 复制代码
    @Transactional
    public void someTransactionalMethod() {
        try {
            // 业务逻辑
        } catch (Exception e) {
            // 捕获异常后重新抛出
            throw new RuntimeException(e);
        }
    }
相关推荐
ClouGence8 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将10 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_2 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
冬奇Lab6 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence6 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神6 天前
三、用户与权限管理
数据库·mysql
麦聪聊数据7 天前
数据服务化时代:企业数据能力输出的核心路径
数据库