首頁 > 軟體

Spring中事務幾個常見的問題解決

2022-08-02 18:08:36

前言

首先,事務這個概念是資料庫層面的,Spring只是基於資料庫中的事務進行擴充套件,以及提供了一些能讓程式設計師更新方便操作事務的方式

Spring如何處理事務

Spring中支援程式設計式事務和宣告式事務管理兩種方式

1、程式設計式事務,可以使用TransactionTemplate

public class B {
    @Autowired
    private TransactionTemplate template;
    
    public void sout(){
        TransactionCallback<Integer> transactionCallback = new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus transactionStatus) {
                //jdbcTemplate.update
                //jdbcTemplate.update
                if(執行失敗){
                    //回滾事務
                    transactionStatus.setRollbackOnly();
                    return -1;
                }
                return 1;
            }
        };

        Integer result =  template.execute(transactionCallback);
    }

當加了@Transactional註解後,Spring會基於這個類生成一個代理物件,會將這個代理物件作為bean,當在使用這個代理物件的方法時,如果這個方法上存在@Transactional註解,那麼代理邏輯會先把事務的自動提交設定為false,然後再去執行原本的業務邏輯方法,如果執行業務邏輯方法沒有出現異常,那麼代理邏輯中就會將事務提交,如果執行業務邏輯方法出現了異常,那麼會將事務進行回滾。

好處:程式碼級別的事務控制,可以自己控制事務的邏輯,比較靈活
缺點:太麻煩,需要自己實現所有的事務邏輯

2、宣告式事務

是Spring在AOP基礎上提供的事務實現機制。

public class B {
    @Autowired
    private TransactionTemplate template;

    @Transactional
    public void sout(){
  System.out.println("=================A=====================");
    }
}

優點:不需要在業務程式碼中新增事務管理的程式碼,只需要在組態檔中做相關的事務規則宣告規則就可以了。
缺點:只能只能針對方法級別,無法控制程式碼級別。

Spring事務傳播機制

Propagation:多個事務方法相互呼叫時,事務是如何在這些方法鍵傳播

方法A是一個事務方法。方法A在執行的過程中呼叫了方法B,那麼方法B有無事務以及方法B對事物的要求不同都會對方法A的事務具體執行造成影響,同時方法A的事務對方法B的事務執行也有影響。這種影響具體是什麼就由兩個方法所定義的事務傳播型別所決定

a呼叫b,以下描述,當前均只a,自己均指b

  • REQUIRED(Spring預設的事務傳播型別):如果當前沒有事務,則自己新建一個事務,如果當前存在事務,則加入這個事務。
  • SUPPORTS:當前存在事務,則加入當前事務,如果當前沒有事務,就以非事務方法執行
  • MANDATORY:當前存在事務,則加入當前事務,如果當前沒有事務,則丟擲異常
  • REQUIRES_NEW:建立一個新事務,如果存在當前事務,則掛起該事務(互不干擾)
  • NOT_SUPPORTED:以非事務方法執行,如果當前存在事務,則掛起當前事務。
  • NEVER:不使用事務,如果當前存在事務,則丟擲異常
  • NESTED:如果當前存在事務,則巢狀事務中執行,否則REQUIRED操作一樣(開啟一個事務)

和REQUIRES_NEW的區別:
REQUIRES_NEW是新建一個事務,並且新開啟的事務與原事務無關,而NESTED則是當前存在事務時(我們把當前事務成為父事務)會開啟一個巢狀事務(稱之為一個子事務)。在NESTED情況下父事務回滾時,子事務也會回滾,而在REQUIRES_NEW情況下,原有事務回滾,不會影響新開啟的子事務。

和REQUIRED的區別:
REQUIRED情況下,呼叫方存在事務時,則被呼叫和呼叫方法使用同一事務,那麼被呼叫方出現異常時,由於共用一個事務,所以無論呼叫方法是否catch異常,事務都會回滾(父子事務一起回滾),而在NESTED情況下,被呼叫方發生異常時,呼叫發可以catch其異常,這樣只有子事務回滾,父事務不受影響(父事務是否需要回滾可以自行決定)

Spring事務隔離級別

  • ISOLATION:Spring的事務隔離級別
  • DEFAULT:使用資料庫預設的事務隔離級別
  • READ_UNCOMMITTED:讀未提交,允許事務在執行過程中,讀取其他事務未提交的資料
  • READ_COMMITTED:讀已提交,允許事務在執行過程中,讀取其他事務已提交的資料
  • REPEATABLE_READ:可重複讀,在同一個事務內,任意時刻的查詢結果是一致的
  • SERIALIZABLE:所有事務依次執行

資料庫設定的隔離級別是read commited,而spring設定的隔離級別是repeatable read,這個時候隔離級別以哪個為準?
以Spring為準(spring設定的會覆蓋資料庫的隔離級別),如果Spring設定的隔離級別資料庫不支援,效果取決於資料庫

到此這篇關於Spring中事務幾個常見的問題解決的文章就介紹到這了,更多相關Spring事務 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com