spring事务-Exception不会回滚

在Spring中,事务管理默认情况下只会在遇到运行时异常(RuntimeException)和错误(Error)时进行回滚。对于检查型异常(Checked Exception),Spring事务默认不会进行回滚。

如果你想让Spring事务在遇到检查型异常时也进行回滚,你可以采取以下几种方法:

方法一:使用@Transactional注解的rollbackFor属性

你可以在@Transactional注解中指定哪些异常发生时应该触发事务回滚,包括检查型异常。

java 复制代码
import org.springframework.transaction.annotation.Transactional;


@Service
public class MyService {


    @Transactional(rollbackFor = Exception.class)
    public void myMethod() throws Exception {
        // ... 业务逻辑 ...
        throw new Exception("发生了一个检查型异常");
    }
}

在上面的例子中,rollbackFor = Exception.class表示任何类型的异常(包括运行时异常和检查型异常)都会触发事务回滚。

方法二:全局配置

如果你想对整个应用进行全局配置,让所有的检查型异常都触发事务回滚,你可以在Spring配置文件中进行如下设置:

xml 复制代码
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" rollback-for="java.lang.Exception"/>
    </tx:attributes>
</tx:advice>


<aop:config>
    <aop:pointcut id="serviceOperation" expression="execution(* com.yourpackage..*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
</aop:config>

或者在Java配置类中使用@EnableTransactionManagementTransactionInterceptor

java 复制代码
@Configuration
@EnableTransactionManagement
public class TransactionConfig implements TransactionManagementConfigurer {


    @Autowired
    private PlatformTransactionManager transactionManager;


    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager;
    }


    @Bean
    public TransactionInterceptor txInterceptor() {
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
        transactionAttribute.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        source.addTransactionalMethod("*", transactionAttribute);
        return new TransactionInterceptor(transactionManager, source);
    }
}

Java

方法三:编程式事务管理

如果你使用编程式事务管理,可以在调用TransactionStatussetRollbackOnly方法来标记事务需要回滚。

java 复制代码
@Service
public class MyService {


    @Autowired
    private PlatformTransactionManager transactionManager;


    public void myMethod() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            // ... 业务逻辑 ...
            throw new Exception("发生了一个检查型异常");
        } catch (Exception ex) {
            status.setRollbackOnly();
        } finally {
            transactionManager.commit(status);
        }
    }
}

注意事项

  • 使用rollbackFor属性时要小心,确保不会因为过于宽泛的异常捕获导致意外的数据不一致。
  • 在设计服务层时,应该尽量避免抛出检查型异常,而是使用运行时异常来表示错误情况,这样可以更好地利用Spring的事务管理机制。

通过上述方法,你可以控制Spring事务在不同异常情况下的行为,确保数据的完整性和一致性。

相关推荐
小江的记录本5 分钟前
【JEECG Boot】 《JEECG Boot 数据字典使用教程》(完整版)
java·前端·数据库·spring boot·后端·spring·mybatis
心勤则明25 分钟前
Spring AI Alibaba 分布式智能体实战:基于 A2A 协议的架构演进与落地
人工智能·分布式·spring
杜子不疼.30 分钟前
AI Agent 智能体开发入门:AutoGen 多智能体协作实战教程
java·人工智能·spring
Java成神之路-37 分钟前
SpringMVC 入门到精通:Servlet 对比、工作流程、Bean 加载控制完整指南(Spring系列11)
spring·servlet
小江的记录本42 分钟前
【JEECG Boot】 JEECG Boot 数据字典管理——六大核心功能(内含:《JEECG Boot 数据字典开发速查清单》)
java·前端·数据库·spring boot·后端·spring·mybatis
小江的记录本42 分钟前
【JEECG Boot】 JEECG Boot——Online表单 系统性知识体系全解
java·前端·spring boot·后端·spring·低代码·mybatis
都说名字长不会被发现44 分钟前
Spring 线程池最佳实践:如何优雅管理多线程任务
java·spring·线程池·并发编程
wok1571 小时前
WebMVC 和 WebFlux 架构选型
java·spring·架构·mvc
希望永不加班1 小时前
SpringBoot 邮件发送:文本邮件与 HTML 邮件
java·spring boot·后端·spring·html
漫霂1 小时前
SpringSecurity入门应用
java·数据库·spring