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

老生常談spring的事務(wù)傳播機制

 更新時間:2021年09月07日 10:26:26   作者:林蝸牛snail  
這篇文章主要介紹了spring的事務(wù)傳播機制,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

spring的事務(wù)傳播機制

背景:實習(xí)期間幾次遇到事務(wù)方法,有一次本地測試時發(fā)現(xiàn)事務(wù)沒有回滾,就把簡單描述寫在wx上,今天來給spring事務(wù)做個自我總結(jié)。

1、why

為什么會有事務(wù)傳播機制?

場景一:

  • serviceA 方法調(diào)用了 serviceB 方法,但兩個方法都有事務(wù),這個時候如果 serviceB 方法異常,是讓 serviceB 方法提交,還是兩個一起回滾。

場景二:

  • serviceA 方法調(diào)用了 serviceB 方法,但是只有 serviceA 方法加了事務(wù),是否把 serviceB 也加入 serviceA 的事務(wù),如果 serviceB 異常,是否回滾 serviceA 。

場景三:

  • serviceA 方法調(diào)用了 serviceB 方法,兩者都有事務(wù),serviceB 已經(jīng)正常執(zhí)行完,但 serviceA 異常,是否需要回滾 serviceB 的數(shù)據(jù)。

所以,我們需要有對應(yīng)的事務(wù)傳播機制來控制事務(wù)。

2、傳播機制生效的條件

有了spring事務(wù)傳播機制,那這種機制存在的條件呢?我們知道,spring的事務(wù)是基于aop的,確切來說,是基于JDK動態(tài)代理的AOP,這種AOP有什么特點呢? 它是基于類或者接口的,也就是說,當(dāng) @Transactional寫在一個方法上時,這個方法將會被spring動態(tài)代理, 生成一個動態(tài)代理類, 對原方法進行修飾增強,但是要注意??! 原先的方法的類并沒有什么不同,并沒有事務(wù),spring動態(tài)代理這個類生成的代理類才有事務(wù),才有增強,也就是說,在同一個類里面通過this.xx()調(diào)用本類的事務(wù)方法時,事務(wù)是不會生效的,因為你調(diào)用的不是代理類。

    @Transactional
    @Override
    public void method1() {
        this.method2(); 
    } 
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void method2() {
       xx
    }

解決方案

關(guān)鍵在于獲取類的代理對象,而不是通過this去調(diào)用,所以以下方法都是基于這個關(guān)鍵點去解決的。

  • 1、最簡單的,兩個事務(wù)方法放在不同的service里面,這個比較簡單,就不給例子了。(推薦)
  • 2、AOP上下文。spring提供了AOP上下文AopContext,因此通過AopContext,可以很方便的獲取到代理對象。
public class Myservice{ 
    @Transactional
    @Override
    public void method1() {
       ((Myservice)AopContext.currentProxy()).method2();
    }
 
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void method2() {
       xx
    }  
}

一運行,報錯了,因為exposeProxy默認(rèn)為false,我們要暴露代理類,就要設(shè)置為true,可以在springboot啟動類上加一個注解

@EnableAspectJAutoProxy(exposeProxy = true)
  • 3、ApplicationContext
public class Myservice{ 
   @Autowired
    ApplicationContext context; 
    Myservice service;
 
    @PostConstruct  //初始化時調(diào)用,不加也行
    private void getMyservice() {
        service = context.getBean(Myservice.class);
    }     
 
    @Transactional
    @Override
    public void method1() {
      service.method2();
    }
 
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void method2() {
       xx
    }  
}

第二和第三種的區(qū)別就在于,2是直接獲取代理類,3是通過調(diào)用getBean間接獲取代理類,總的來說,第一種是最方便的,也是最推薦的做法。

3、傳播機制類型

下面的類型都是針對于被調(diào)用方法來說的,理解起來要想象成兩個 service 方法的調(diào)用才可以。

PROPAGATION_REQUIRED (默認(rèn))

  • 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),則新建事務(wù)
  • 如果當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù),合并成一個事務(wù)

REQUIRES_NEW (一般用在子方法需要單獨事務(wù))

  • 新建事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起
  • 這個方法會獨立提交事務(wù),不受調(diào)用者的事務(wù)影響,父級異常,它也是正常提交
  • (上面兩個類型是常用的,下面的比較少用)

NESTED

  • 如果當(dāng)前存在事務(wù),它將會成為父級事務(wù)的一個子事務(wù),方法結(jié)束后并沒有提交,只有等父事務(wù)結(jié)束才提交
  • 如果當(dāng)前沒有事務(wù),則新建事務(wù)
  • 如果它異常,父級可以捕獲它的異常而不進行回滾,正常提交
  • 但如果父級異常,它必然回滾,這就是和 REQUIRES_NEW 的區(qū)別

SUPPORTS

  • 如果當(dāng)前存在事務(wù),則加入事務(wù)
  • 如果當(dāng)前不存在事務(wù),則以非事務(wù)方式運行,這個和不寫沒區(qū)別

NOT_SUPPORTED

  • 以非事務(wù)方式運行
  • 如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起

MANDATORY

  • 如果當(dāng)前存在事務(wù),則運行在當(dāng)前事務(wù)中
  • 如果當(dāng)前無事務(wù),則拋出異常,也即父級方法必須有事務(wù)

NEVER

  • 以非事務(wù)方式運行,如果當(dāng)前存在事務(wù),則拋出異常,即父級方法必須無事務(wù)

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

相關(guān)文章

  • Spring注解@Value及屬性加載配置文件方式

    Spring注解@Value及屬性加載配置文件方式

    這篇文章主要介紹了Spring注解@Value及屬性加載配置文件方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • eclipse如何搭建Springboot項目詳解

    eclipse如何搭建Springboot項目詳解

    今天帶大家學(xué)習(xí)eclipse如何搭建Spring boot項目,文中有非常詳細(xì)的圖文解說,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java多文件生成并壓縮下載功能(思路詳解)

    Java多文件生成并壓縮下載功能(思路詳解)

    這篇文章主要介紹了Java多文件生成并壓縮下載,本文給大家分享兩種思路通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Spring與Mybatis相結(jié)合實現(xiàn)多數(shù)據(jù)源切換功能

    Spring與Mybatis相結(jié)合實現(xiàn)多數(shù)據(jù)源切換功能

    這篇文章主要介紹了Spring與Mybatis相結(jié)合實現(xiàn)多數(shù)據(jù)源切換功能的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • java基于Apache FTP實現(xiàn)文件上傳、下載、修改文件名、刪除

    java基于Apache FTP實現(xiàn)文件上傳、下載、修改文件名、刪除

    本篇文章主要介紹了Apache FTP實現(xiàn)文件上傳、下載、修改文件名、刪除,實現(xiàn)了FTP文件上傳(斷點續(xù)傳)、FTP文件下載、FTP文件重命名、FTP文件刪除等功能,有需要的可以了解一下。
    2016-11-11
  • 淺析Mysql中的視圖

    淺析Mysql中的視圖

    這篇文章主要介紹了淺析Mysql中的視圖,視圖是從一個或者多個表中導(dǎo)出的表,視圖的行為與表非常相似,在視圖中用戶可以使用SELECT語句查詢數(shù)據(jù),以及使用INSERT、UPDATE和DELETE修改記錄,需要的朋友可以參考下
    2023-05-05
  • Java計算兩個時間段的差的實例詳解

    Java計算兩個時間段的差的實例詳解

    在本篇內(nèi)容中,我們給大家整理了關(guān)于Java計算兩個時間段的差的實例內(nèi)容,并做了詳細(xì)分析,有需要的朋友們學(xué)習(xí)下。
    2022-11-11
  • Java多線程連續(xù)打印abc實現(xiàn)方法詳解

    Java多線程連續(xù)打印abc實現(xiàn)方法詳解

    這篇文章主要介紹了Java多線程連續(xù)打印abc實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • springBoot系列常用注解(小結(jié))

    springBoot系列常用注解(小結(jié))

    這篇文章主要介紹了springBoot系列常用注解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java如何批量執(zhí)行datax腳本

    Java如何批量執(zhí)行datax腳本

    這篇文章主要介紹了Java如何批量執(zhí)行datax腳本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02

最新評論