SpringBoot配置全局事務管理


基於 SpringBoot 4.5

一、注解方式

1、在SpringBoot的啟動類上加入

@EnableTransactionManagement

@SpringBootApplication
// 開啟事務支持
@EnableTransactionManagement
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

2、在需要事務支持的類(class)或方法(method)上,加上注解並設置其屬性

/* 
 * 表明該類(class)或方法(method)受事務控制
 * @param propagation  設置隔離級別
 * @param isolation 設置傳播行為
 * @param rollbackFor 設置需要回滾的異常類,默認為RuntimeException
 */
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
@Service
public class UserServiceImpl implements UserService {
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public int addUser(User user) {
        return userMapper.addUser(user);
    }
}


二、AOP的方式

package com.pro.config;

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.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import java.util.Collections;


/**
 * 全局事務配置類
 */
@Aspect
@Configuration
public class TransactionConfig {
    // 切入點
    private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.pro.service.*.*(..))";
    // 需要添加事務切入的方法列表, 使用這些前綴的方法都會被添加事務
    private static final String[] REQUIRED_RULE_TRANSACTION = {"insert*", "create*", "add*", "save*", "update*", "del*", "delete*"};
    private static final String[] READ_RULE_TRANSACTION = {"select*", "get*", "query*", "search*", "count*", "find*"};

    @Autowired
//    private PlatformTransactionManager transactionManager;
    private TransactionManager transactionManager;

    @Bean
    public TransactionInterceptor txAdvice() {
        // 增刪改事務
        RuleBasedTransactionAttribute REQUIRED = new RuleBasedTransactionAttribute();
        // 當拋出設置的對應異常后,進行事務回滾(此處設置為“Exception”級別)
        REQUIRED.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        // 設置隔離級別(讀已提交的數據)
        REQUIRED.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        // 設置傳播行為(存在事務則加入其中,不存在則新建事務)
        REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        // 只讀事務,不做更新操作
        RuleBasedTransactionAttribute READONLY = new RuleBasedTransactionAttribute();
        // 當拋出設置的對應異常后,進行事務回滾(此處設置為“Exception”級別)
        READONLY.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        // 設置隔離級別(讀已提交的數據)
        READONLY.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        // 設置傳播行為(如果當前存在事務,則加入這個事務,如果當前沒有事務,就以非事務方式執行)
        READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
        // 設置事務是否“只讀”(非必需,只是聲明該事務中不會進行修改數據庫的操作,可減輕由事務造成的數據庫壓力,屬於性能優化的推薦配置)
        READONLY.setReadOnly(true);

        // 事務管理規則,承載需要進行事務管理的方法名(模糊匹配)及設置的事務管理屬性
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        // 增刪改方法的前綴
        for (String s : REQUIRED_RULE_TRANSACTION) {
            source.addTransactionalMethod(s, REQUIRED);
        }
        // 查詢方法的前綴
        for (String s : READ_RULE_TRANSACTION) {
            source.addTransactionalMethod(s, READONLY);
        }

        // 實例化事務攔截器
        return new TransactionInterceptor(transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        // 聲明切點要切入的面
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        // 設置需要被攔截的路徑
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        // 設置切面和配置好的事務管理
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM