欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot AOP如何配置全局事務(wù)

 更新時間:2024年05月11日 11:44:03   作者:X爪哇程序猿  
這篇文章主要介紹了SpringBoot AOP如何配置全局事務(wù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

SpringBoot的出現(xiàn)使得項目中使用事務(wù)變得非常簡單,有兩種使用方式,適合小型項目的注解事務(wù)(聲明式事務(wù)管理),適合大型項目的全局事務(wù)。

1、注解事務(wù)(次要)

注解事務(wù)使用只用兩步,開啟事務(wù)注解功能,使用事務(wù)注解功能,并且每步都只有使用一個注解。

第一步

開啟事務(wù)注解功能@EnableTransactionManagement

在主啟動類中添加注解@EnableTransactionManagement即可。

package com.gx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement //開啟事務(wù)注解功能
@SpringBootApplication
public class Ch09SpringbootTransAnnoApplication {

    public static void main(String[] args) {
        SpringApplication.run(Ch09SpringbootTransAnnoApplication.class, args);
    }

}

第二步

使用事務(wù)注解功能@Transactional

在service接口實現(xiàn)類或接口實現(xiàn)類方法上添加@Transactional即可。

package com.gx.service.impl;

import com.gx.service.StudentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gx.domain.Student;

@Service
public class StudentServiceImpl implements StudentService {

    @Transactional //使用注解事務(wù)
    @Override
    public String addStudent(Student student) {
        //業(yè)務(wù)方法
    }
}

注意事項:@Transactional必須添加在public修飾的方法上。

2、全局事務(wù)(主要)

SpringBoot全局事務(wù)主要使用AOP切面編程。

第一步

創(chuàng)建切面類@Aspect。

創(chuàng)建一個普通的類,加上@Aspect后該類就是一個切面類了,用于編寫事務(wù)功能。

同時還需要把該切面類定義為一個配置類,添加注解@Configuration即可。

注意事項:

1、@Aspect將該類定義為切面類,把當前類作為一個切面被容器讀取。

? 2、@Configuration將該類定義為配置類,配置spring容器,注入bean

package com.gx.config;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;

@Aspect //定義切面類,把當前類標識為一個切面供容器讀取
@Configuration //定義配置類
public class TransactionAdviceConfig {
	//增強方法
}

第二步

創(chuàng)建第一個方法,返回事務(wù)攔截器(TransactionInterceptor),聲明業(yè)務(wù)方法的事務(wù)屬性,并且注冊到bean中。

需要返回事務(wù)攔截器TransactionInterceptor,就需要new一個TransactionInterceptor。

根據(jù)TransactionInterceptor的類可得知,創(chuàng)建一個TransactionInterceptor目前只有兩個方法。

public TransactionInterceptor() {
    
}

public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
    this.setTransactionManager(ptm);
    this.setTransactionAttributeSource(tas);
}

要使用事務(wù),就要有事務(wù)管理器TransactionManager和事務(wù)屬性TransactionAttributeSource。

配置事務(wù)屬性時一般都是通過方法的名字篩選,比如add*、save*delete*等,所以事務(wù)屬性使用的是他的子類NameMatchTransactionAttributeSource。

//事務(wù)管理器
@Autowired
private TransactionManager transactionManager;

@Bean
public TransactionInterceptor txAdvice() {
    //聲明一個通過方法名字配置事務(wù)屬性的對象
	NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
	//返回一個事務(wù)攔截器
    return new TransactionInterceptor(transactionManager, source);
}

通過方法名稱設(shè)置業(yè)務(wù)方法事務(wù)屬性。

NameMatchTransactionAttributeSource類中我們使用的頻繁的就兩個方法。

setNameMap其實就是addTransactionalMethod的集合。

//通過map集合給多個方法或者多類方法設(shè)置事務(wù)屬性
public void setNameMap(Map<String, TransactionAttribute> nameMap) {
    nameMap.forEach(this::addTransactionalMethod);
}
//通過方法名稱或一類方法名稱和事務(wù)屬性,給一個方法或一類方法設(shè)置事務(wù)屬性
public void addTransactionalMethod(String methodName, TransactionAttribute attr) {
    if (logger.isDebugEnabled()) {
        logger.debug("Adding transactional method [" + methodName + "] with attribute [" + attr + "]");
    }
    if (this.embeddedValueResolver != null && attr instanceof DefaultTransactionAttribute) {
        ((DefaultTransactionAttribute) attr).resolveAttributeStrings(this.embeddedValueResolver);
    }
    this.nameMap.put(methodName, attr);
}

設(shè)置事務(wù)屬性。

TransactionAttribute:事務(wù)屬性,有很多實現(xiàn)的實現(xiàn)類,一般使用基于規(guī)則的事務(wù)屬性RuleBasedTransactionAttribute。

功能大部分在他的父類DefaultTransactionDefinition中。

只寫一小部分,其他可以根據(jù)業(yè)務(wù)需求寫事務(wù)屬性。

//配置一個事務(wù)屬性(只讀)
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
//是否只讀
readOnlyTx.setReadOnly(true);
//事務(wù)傳播行為
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

//通過方法名稱設(shè)置業(yè)務(wù)方法事務(wù)屬性
Map<String, TransactionAttribute> txMap = new HashMap<>();
txMap.put("get*", readOnlyTx);

再添加到NameMatchTransactionAttributeSource

source.setNameMap(txMap);

設(shè)置事務(wù)屬性的方法

  • 1、事務(wù)傳播行為 setPropagationBehavior();
  • 2、事務(wù)隔離級別 setIsolationLevel();
  • 3、事務(wù)超時時間 setTimeout();
  • 4、事務(wù)只讀 setReadOnly();
  • 5、設(shè)置事務(wù)名稱 setName();
  • 6、設(shè)置回滾規(guī)則 setRollbackRules();

事務(wù)屬性。(擴展)

事務(wù)傳播行為

事務(wù)行為說明
PROPAGATION_REQUIRED支持當前事務(wù),假設(shè)當前沒有事務(wù)。就新建一個事務(wù)
PROPAGATION_SUPPORTS支持當前事務(wù),假設(shè)當前沒有事務(wù),就以非事務(wù)方式運行
PROPAGATION_MANDATORY支持當前事務(wù),假設(shè)當前沒有事務(wù),就拋出異常
PROPAGATION_REQUIRES_NEW新建事務(wù),假設(shè)當前存在事務(wù)。把當前事務(wù)掛起
PROPAGATION_NOT_SUPPORTED以非事務(wù)方式運行操作。假設(shè)當前存在事務(wù),就把當前事務(wù)掛起
PROPAGATION_NEVER以非事務(wù)方式運行,假設(shè)當前存在事務(wù),則拋出異常
PROPAGATION_NESTED如果當前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當前沒有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類似的操作。

事務(wù)隔離級別,事務(wù)的隔離級別只用4種但是spring提供有5種。(spring的隔離級別名字與數(shù)據(jù)庫中的不一樣)

隔離級別說明臟讀幻讀不可重復讀
ISOLATION_DEFAULT默認隔離級別,每種數(shù)據(jù)庫支持的事務(wù)隔離級別不一樣,根據(jù)使用的數(shù)據(jù)庫改變。---
ISOLATION_READ_UNCOMMITTED讀未提交,即能夠讀取到?jīng)]有被提交的數(shù)據(jù)。
ISOLATION_READ_COMMITTED讀已提交,即能夠讀到那些已經(jīng)提交的數(shù)據(jù)。
ISOLATION_REPEATABLE_READ重復讀取,即在數(shù)據(jù)讀出來之后加鎖。這個事務(wù)不結(jié)束,別的事務(wù)無法操作這條數(shù)據(jù)。
ISOLATION_SERIALIZABLE串行化,最高的事務(wù)隔離級別,不管多少事務(wù),挨個運行完一個事務(wù)的所有子事務(wù)之后才可以執(zhí)行另外一個事務(wù)里面的所有子事務(wù)。

第三步

配置適配器(Advisor),增強事務(wù)。

創(chuàng)建適配器(一個普通的方法返回Advisor)。

Advisor(顧問)是由切入點和Advice(通知)組成的,但是Advisor是一個接口,需要實現(xiàn)它實現(xiàn)類DefaultPointcutAdvisor,并且傳入?yún)?shù)切入點和Adivce。

@Bean
public Advisor txAdviceAdvisor() {
    //增強事務(wù),關(guān)聯(lián)切入點和事務(wù)屬性
    return new DefaultPointcutAdvisor(切入點, Advice);
}

配置切入點。

//配置切入點表達式 : 指定哪些包中的類使用事務(wù),設(shè)置為靜態(tài)類常量
private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.***.service.*.*(..))";

//一下內(nèi)容放在適配器方法內(nèi)
//配置事務(wù)切入點表達式
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);

關(guān)聯(lián)切入點和Advice。

//增強事務(wù),關(guān)聯(lián)切入點和事務(wù)屬性
return new DefaultPointcutAdvisor(pointcut, txAdvice());

第四步

重啟測試!

最后奉上aop全局事務(wù)全部代碼

package com.gx.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.TransactionManager;
import org.springframework.transaction.interceptor.*;

import javax.sql.DataSource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Aspect //定義切面類,把當前類標識為一個切面供容器讀取
@Configuration //定義配置類
public class TransactionAdviceConfig {

    //事務(wù)的超時時間為10秒
    private static final int TX_METHOD_TIMEOUT = 10;

    //配置切入點表達式 : 指定哪些包中的類使用事務(wù)
    private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.***.service.*.*(..))";

    //事務(wù)管理器
    @Autowired
    private TransactionManager transactionManager;
    /**
     * 聲明業(yè)務(wù)方法的事務(wù)屬性
     */
    @Bean
    public TransactionInterceptor txAdvice() {

        /**
         * 這里配置只讀事務(wù)
         */
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setReadOnly(true);//是否只讀
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//事務(wù)的傳播行為

        /**
         * 必須帶事務(wù)
         * 當前存在事務(wù)就使用當前事務(wù),當前不存在事務(wù),就開啟一個新的事務(wù)
         */
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        //檢查型異常也回滾
        requiredTx.setRollbackRules(
                Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        requiredTx.setTimeout(TX_METHOD_TIMEOUT);

        /**
         * 無事務(wù)地執(zhí)行,掛起任何存在的事務(wù)
         */
        RuleBasedTransactionAttribute noTx = new RuleBasedTransactionAttribute();
        noTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);

        /**
         * 設(shè)置方法對應(yīng)的事務(wù)
         */
        Map<String, TransactionAttribute> txMap = new HashMap<>();
        //只讀事務(wù)
        txMap.put("get*", readOnlyTx);
        txMap.put("query*", readOnlyTx);
        txMap.put("find*", readOnlyTx);
        txMap.put("list*", readOnlyTx);
        txMap.put("count*", readOnlyTx);
        txMap.put("exist*", readOnlyTx);
        txMap.put("search*", readOnlyTx);
        txMap.put("fetch*", readOnlyTx);
        //無事務(wù)
        txMap.put("noTx*", noTx);
        //寫事務(wù)
        txMap.put("add*", requiredTx);
        txMap.put("save*", requiredTx);
        txMap.put("insert*", requiredTx);
        txMap.put("update*", requiredTx);
        txMap.put("modify*", requiredTx);
        txMap.put("delete*", requiredTx);
		
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        source.setNameMap(txMap);
        
		//返回事務(wù)攔截器
        return new TransactionInterceptor(transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        //配置事務(wù)切入點表達式
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        //增強事務(wù),關(guān)聯(lián)切入點和事務(wù)屬性
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java?NIO?Channel?使用詳情

    Java?NIO?Channel?使用詳情

    這篇文章主要介紹了Java?NIO?Channel?使用詳情,文章圍繞主題展開詳細內(nèi)容需要的小伙伴可以參考一下,希望對你的學習有所幫助
    2022-04-04
  • Freemaker Replace函數(shù)的正則表達式運用

    Freemaker Replace函數(shù)的正則表達式運用

    這篇文章主要介紹了Freemaker Replace函數(shù)的正則表達式運用 的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • 解決IDEA2020.1.2IDEA打不開的問題(最新分享)

    解決IDEA2020.1.2IDEA打不開的問題(最新分享)

    由于idea安裝多了某個jar,點擊出現(xiàn)讀條后閃退情況,接下來通過本文給大家分享解決IDEA2020.1.2IDEA打不開的問題,非常不錯,具有一定的參考借鑒價值,感興趣的朋友跟隨小編一起看看吧
    2020-07-07
  • java ClassLoader機制詳細講解

    java ClassLoader機制詳細講解

    ClassLoader一個經(jīng)常出現(xiàn)又讓很多人望而卻步的詞,本文將試圖以最淺顯易懂的方式來講解 ClassLoader,希望能對不了解該機制的朋友起到一點點作用
    2016-07-07
  • Spring的事務(wù)控制實現(xiàn)方法

    Spring的事務(wù)控制實現(xiàn)方法

    這篇文章主要為大家詳細介紹了Spring的事務(wù)控制實現(xiàn)方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 基于Java快速實現(xiàn)一個簡單版的HashMap詳解

    基于Java快速實現(xiàn)一個簡單版的HashMap詳解

    這篇文章主要為大家詳細介紹了如何利用Java簡單實現(xiàn)一個底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組?+?鏈表的HashMap,不考慮鏈表長度超過8個時變?yōu)榧t黑樹的情況,需要的可以參考一下
    2023-02-02
  • Spring Bean生命周期之Bean的注冊詳解

    Spring Bean生命周期之Bean的注冊詳解

    這篇文章主要為大家詳細介紹了Spring Bean生命周期之Bean的注冊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java常見的四種負載均衡算法

    Java常見的四種負載均衡算法

    本文主要介紹了Java常見的四種負載均衡算法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • JAVAWEB實現(xiàn)簡單的商城項目(一)實例代碼解析

    JAVAWEB實現(xiàn)簡單的商城項目(一)實例代碼解析

    本文給大家分享一段實例代碼給大家介紹JAVAWEB實現(xiàn)簡單的商城項目(一),非常具有參考價值,感興趣的朋友一起學習吧
    2016-02-02
  • 使用SpringBoot開發(fā)Restful服務(wù)實現(xiàn)增刪改查功能

    使用SpringBoot開發(fā)Restful服務(wù)實現(xiàn)增刪改查功能

    Spring Boot是由Pivotal團隊提供的全新框架,其設(shè)計目的是用來簡化新Spring應(yīng)用的初始搭建以及開發(fā)過程。這篇文章主要介紹了基于SpringBoot開發(fā)一個Restful服務(wù),實現(xiàn)增刪改查功能,需要的朋友可以參考下
    2018-01-01

最新評論