Springboot全局事務處理


什么是全局事務 Spring Boot(Spring)事務是通過aop(aop相關術語:通知(Advice)、連接點(Joinpoint)、切入點(Pointcut)、切面(Aspect)、目標(Target)、代理(Proxy)、織入(Weaving))切面編程來實現的,此時我們就可以對指定的包的service的方法進行事務控制.

為什么要使用全局事務 在實際開發中,有些同學命名方法時不規范,多個成員開發時,會造成混亂,維護成本特別高,代碼可讀性不高.

怎么配置Spring Boot全局事務 Spring Boot使用事務是非常簡單的,只需要在配置類或者啟動類上添加注解@EnableTransactionManagement開啟事務支持,然后在service層添加注解 @Transactional(rollbackFor = Exception.class)即可. 下面是全局事務代碼實現

 特別提醒:mysql對應的表必須是InnoDB型才可支持事務,myisam不支持事務
package com.test.sketelon.util.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.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;
​
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
​
/**
 * 全局事物配置
 *
 * @author David_hua
 * @date 2019/8/15
 * REQUIRED :如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。
 * SUPPORTS :如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
 * MANDATORY :如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
 * REQUIRES_NEW :創建一個新的事務,如果當前存在事務,則把當前事務掛起。
 * NOT_SUPPORTED :以非事務方式運行,如果當前存在事務,則把當前事務掛起。
 * NEVER :以非事務方式運行,如果當前存在事務,則拋出異常。
 * NESTED :如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價於 REQUIRED 。
 * 指定方法:通過使用 propagation 屬性設置,例如:@Transactional(propagation = Propagation.REQUIRED)
 * 參考文章;https://blog.csdn.net/schcilin/article/details/93306826
 */
@Aspect
@Configuration
public class TransactionAdviceConfig {
​
    /**
     * 配置方法過期時間,默認-1,永不超時
     */
    private final static int TX_METHOD_TIME_OUT = 10;
​
    /**
     * 全局事務位置配置 在哪些地方需要進行事務處理:具體如下
     * 配置切入點表達式,這里解釋一下表達式的含義
     * 1.execution(): 表達式主體
     * 2.第一個*號:表示返回類型,*號表示所有的類型
     * 3.com.schcilin.goods.service表示切入點的包名
     * 4.第二個*號:表示實現包
     * 5.*(..)*號表示所有方法名,..表示所有類型的參數
     */
    private static final String POITCUT_EXPRESSION = "execution(* com.test.sketelon.service.*.*(..))";
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
​
    @Bean
    public TransactionInterceptor txadvice() {
        /** 配置事務管理規則
         nameMap聲明具備需要管理事務的方法名.
         這里使用public void addTransactionalMethod(String methodName, TransactionAttribute attr)
         */
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        Map<String, TransactionAttribute> nameMap = new HashMap<>(16);
        /*只讀事物、不做更新刪除等*/
        /*事務管理規則*/
        RuleBasedTransactionAttribute readOnlyRule = new RuleBasedTransactionAttribute();
        /*設置當前事務是否為只讀事務,true為只讀*/
        readOnlyRule.setReadOnly(true);
        /* transactiondefinition 定義事務的隔離級別;
         *  PROPAGATION_REQUIRED 如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中*/
        readOnlyRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        RuleBasedTransactionAttribute requireRule = new RuleBasedTransactionAttribute();
        /*拋出異常后執行切點回滾*/
        requireRule.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        /*PROPAGATION_REQUIRED:事務隔離性為1,若當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。這是默認值。 */
        requireRule.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        /*設置事務失效時間,超過10秒,可根據hytrix,則回滾事務*/
        requireRule.setTimeout(TX_METHOD_TIME_OUT);
​
        nameMap.put("add*", requireRule);
        nameMap.put("save*", requireRule);
        nameMap.put("insert*", requireRule);
        nameMap.put("update*", requireRule);
        nameMap.put("delete*", requireRule);
        nameMap.put("remove*", requireRule);
        /*進行批量操作時*/
        nameMap.put("batch*", requireRule);
        nameMap.put("get*", readOnlyRule);
        nameMap.put("query*", readOnlyRule);
        nameMap.put("find*", readOnlyRule);
        nameMap.put("select*", readOnlyRule);
        nameMap.put("count*", readOnlyRule);
        source.setNameMap(nameMap);
        return new TransactionInterceptor(platformTransactionManager, source);
    }
​
    /**
     * 設置切面=切點pointcut+通知TxAdvice
     *
     * @return
     */
    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(POITCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txadvice());
    }
}

  


總結 以上是整個Spring Boot事務的解釋及其使用.spring是以aop切面編程思想管理整個事務的創建,提交和回滾的.支持編程式事務和聲明式事務.在實際項目中,聲明式事務使用的相對比較簡單一些,但是在處理更小粒度的操作時,就需要編程式事務啦.更有是在實際中,有可能使用多個事務管理器(jdbc和jta)兩種.此時就需要指定事務管理器

 


免責聲明!

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



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