在Springboot中如何配置全局的transaction事务

本文介绍了一种在SpringBoot中通过AOP实现全局事务管理的方法,避免了在每个Service方法上手动添加@Transactional注解的繁琐步骤。通过配置特定的切入点表达式和事务属性,可以自动为指定的数据操作方法添加事务支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

一般来说,springboot实现事务只需要 在public方法头上加上@Transactional注解即可,@Transactional 默认只捕获RuntimeException.class,对Exception异常得需要 @Transactional(rollbackFor = {Exception.class}) 捕获回滚。这个有个问题就是:当项目特别大的时候,对所有的service 都去加上事务 ,显得非常麻烦。

方案

 可以通过spring AOP 方式实现配置全局的transaction事务。JAVA代码例子如下:

package com.demo.app.datasource;

import com.demo.framelib.datasource.MultipleDataSource;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Description:事务操作类.
  事务管理配置,拦截指定包下所有方法
 */
@Aspect
@Component
@AutoConfigureAfter(MultipleDataSourceConfiguration.class)
public class TxAdviceInterceptor {

    /**
     * basicDataSource.
     */
    @Value("${tx_method_timeout}")
    private int txMethodTimeout;
    /**
     * basicDataSource.
     */
    @Value("${aop_pointcut_expression}")
    private String aopPointcutExpression;
    
    /**
     * DataSourceTransactionManager.
     * @param multipleDataSource multipleDataSource
     * @return dataSourceTransactionManager.
     */
    @Bean(name = "dataSourceTransactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager(
            @Qualifier("multipleDataSource") MultipleDataSource multipleDataSource) {
        DataSourceTransactionManager dataSourceTransactionManager =
                new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(multipleDataSource);
        return dataSourceTransactionManager;
    }
    
    /**
     * 事务配置
     */
    @Bean(name = "txAdvice")
    public TransactionInterceptor txAdvice(
            @Qualifier("dataSourceTransactionManager") DataSourceTransactionManager dataSourceTransactionManager) {
        /* 只读事务,不做更新操作 */
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setReadOnly(true);
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);

        /* 当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务 */
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        /*requiredTx.setTimeout(txMethodTimeout);*/
        Map<String, TransactionAttribute> txMap = new HashMap<>();
        txMap.put("add*", requiredTx);
        txMap.put("create*", requiredTx);
        txMap.put("modify*", requiredTx);
        txMap.put("save*", requiredTx);
        txMap.put("insert*", requiredTx);
        txMap.put("update*", requiredTx);
        txMap.put("delete*", requiredTx);
        txMap.put("remove*", requiredTx);
        txMap.put("get*", readOnlyTx);
        txMap.put("query*", readOnlyTx);
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        source.setNameMap(txMap);
        TransactionInterceptor txAdvice =
                new TransactionInterceptor(dataSourceTransactionManager, source);
        return txAdvice;        
    }

    /**
     * 利用AspectJExpressionPointcut设置切点
     */
    @Bean(name = "txPointcut")
    public AspectJExpressionPointcut txPointcut() {
        AspectJExpressionPointcut txPointcut = new AspectJExpressionPointcut();
        txPointcut.setExpression(aopPointcutExpression);
        return txPointcut;
    }
    
    /**
      * 声明切面(Aspect):切面就是通知和切入点的结合。
      * 通知和切入点共同定义了关于切面的全部内容——它的功能、在何时和何地完成其功能
      */
    @Bean
    public Advisor txAdviceAdvisor(
        @Qualifier("txAdvice") TransactionInterceptor txAdvice,
        @Qualifier("txPointcut") AspectJExpressionPointcut txPointcut) {        
        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor(txPointcut, txAdvice);
        defaultPointcutAdvisor.setOrder(2);
        return defaultPointcutAdvisor;
    }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值