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

问题

一般来说,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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Spring Boot 实现全局事务配置和数据源配置可以通过整合 Spring Boot 和 Spring 的事务管理机制以及使用 Spring Boot 自带的数据库连接池实现。 以下是一个简单的示例,展示如何在 Spring Boot 配置全局事务和数据源: 1. 在 pom.xml 文件添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` 2. 在 application.properties 文件添加以下配置: ``` spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root # JPA 配置 spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update # 全局事务配置 spring.transaction.default-timeout=60 spring.transaction.rollback-on-commit-failure=true spring.transaction.rollback-on-rollback-failure=true ``` 3. 在您的代码添加以下注释: ``` @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) ``` 这将确保在事务方法执行的所有操作都将在单个事务进行,并在发生异常时回滚。 4. 在您的代码使用 Spring Boot 自带的 JdbcTemplate 或 JPA 进行数据库操作。 ``` @Autowired private JdbcTemplate jdbcTemplate; public void insert() { jdbcTemplate.update("INSERT INTO users (name, age) VALUES (?, ?)", "Tom", 20); } ``` 或者 ``` @Autowired private UserRepository userRepository; public void insert() { User user = new User(); user.setName("Tom"); user.setAge(20); userRepository.save(user); } ``` 以上就是在 Spring Boot 配置全局事务和数据源的示例。请注意,这只是一个简单的示例,实际实现可能会更复杂,具体实现取决于您的应用程序需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值