国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring Boot】事務的隔離級別與事務的傳播特性詳解:如何在 Spring 中使用事務?不同隔離級別的區(qū)別?

這篇具有很好參考價值的文章主要介紹了【Spring Boot】事務的隔離級別與事務的傳播特性詳解:如何在 Spring 中使用事務?不同隔離級別的區(qū)別?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


1 事務

1.1 事務簡介與 mysql 中的事務使用

事務這個詞在學習 MySQL 和多線程并發(fā)編程的時候,想必大家或多或少接觸過。那么什么是事務呢?

事務是指一組操作作為一個不可分割的執(zhí)行單元,要么全部成功執(zhí)行,要么全部失敗回滾。在數據庫中,事務可以保證數據的一致性、完整性和穩(wěn)定性,同時避免了數據的異常和不一致情況。常見的事務包括插入、更新、刪除等數據庫操作。事務的核心要素是ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)。

比如,常見的轉賬操作,以小明給小紅轉賬100元為例,分為如下兩個操作:

  1. 小明的賬戶 -100元;
  2. 小紅的賬戶 +100元。

如果沒有事務,第一步操作執(zhí)行成功,而第二步執(zhí)行失敗,就會導致小明賬戶平白無故的扣款而小紅賬戶沒有收到款項的問題。因此,事務的存在是必要的,這一組操作要么全部執(zhí)行成功,要么一起失敗~
springboot事務級別,JavaEE編程之路,spring,spring boot,后端

在 MySQL 中,事務有三個重要的操作,分別為:開啟事務、提交事務、回滾事務,對應的操作命令如下:

-- 開啟事務
start transaction;
-- 業(yè)務執(zhí)行
...
-- 提交事務
commit;
-- 回滾事務
rollback;

1.2 Spring 編程式事務(手動操作)

與 MySQL 操作事務類似,Spring 手動操作事務也需要三個重要的操作:開啟事務(獲取事務)、提交事務、回滾事務。

SpringBoot 內置了兩個對象:

  • DataSourceTransactionManager ?來獲取事務(開啟事務)、提交或回滾事務的;
  • TransactionDefinition 是事務的屬性,在獲取事務的時候需要將TransactionDefinition 傳遞進去從?獲得?個事務 TransactionStatus;

實現代碼如下:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    // 事務管理器
    @Autowired
    private DataSourceTransactionManager transactionManager;
    // 定義事務屬性
    @Autowired
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/add")
    public int add(UserInfo userInfo) {
        // 非空校驗
        if (userInfo == null || !StringUtils.hasLength(userInfo.getUsername())
            || !StringUtils.hasLength(userInfo.getPassword())) {
            return 0;
        }
        // 1. 開始事務
        TransactionStatus transactionStatus =
                transactionManager.getTransaction(transactionDefinition);
        int result = userService.add(userInfo);
        System.out.println("添加: " + result);
//        // 2. 回滾事務
//        transactionManager.rollback(transactionStatus);
        // 3. 提交事務
        transactionManager.commit(transactionStatus);
        return result;
    }
}

從上述代碼可以看出,雖然可以實現事務,但是操作很繁瑣。因此,我們 常常使用另一種更簡單的方式:基于注解的聲明式事務。

1.3 Spring 聲明式事務(自動操作)

相比手動操作事務來說,聲明式事務非常簡單,只需要在需要的方法上添加 @Transactional 注解,無需手動開啟事務和提交事務。

示例代碼如下:

@Transactional // 聲明式事務(自動提交)
@RequestMapping("/insert")
public Integer insert(UserInfo userInfo) {
    // 非空校驗
    if (userInfo == null || !StringUtils.hasLength(userInfo.getUsername())
            || !StringUtils.hasLength(userInfo.getPassword())) {
        return 0;
    }
    int result = userService.add(userInfo);
    return result;
}

對于 @Transactional 的幾點說明:

  1. 該注解可以加在方法或者類上,若加在類上,則說明該類的所有公共方法可以自動的開啟和提交事務 ,無論修飾方法還是類,都只對 public 方法有效;
  2. 在方法執(zhí)行前自動開啟事務,在方法執(zhí)行完畢(沒有發(fā)生任何異常)自動提交事務。如果 在方法執(zhí)行期間出現異常,會自動回滾事務。

附:@Transactional 的常見參數:

參數 說明
propagation 定義了事務方法被嵌套調用時,事務如何傳播到被調用的方法。常見取值包括:
- REQUIRED(默認):如果當前存在事務,則加入該事務;如果當前沒有事務,則創(chuàng)建一個新的事務。
- REQUIRES_NEW:每次調用方法時都會創(chuàng)建一個新的事務,如果存在當前事務,則將其掛起。
- SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務方式執(zhí)行。
- NOT_SUPPORTED:以非事務方式執(zhí)行操作,如果當前存在事務,則將其掛起。
- MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
- NEVER:以非事務方式執(zhí)行操作,如果當前存在事務,則拋出異常。
- NESTED:如果當前存在事務,則在嵌套事務內執(zhí)行;如果當前沒有事務,則創(chuàng)建一個新的事務。
isolation 定義了事務并發(fā)執(zhí)行時,事務之間的隔離程度。常見取值包括:
- DEFAULT(默認):使用數據庫默認的隔離級別。
- READ_UNCOMMITTED:最低的隔離級別,事務可以讀取未提交的數據。
- READ_COMMITTED:事務只能讀取已提交的數據。
- REPEATABLE_READ:事務在整個過程中保持一致的讀取視圖,防止臟讀和不可重復讀。
- SERIALIZABLE:最高的隔離級別,事務串行執(zhí)行,避免臟讀、不可重復讀和幻讀。
timeout 定義了事務執(zhí)行的最長時間,單位為秒。默認值為-1,表示沒有超時限制。
readOnly 如果設置為true,表示事務只讀,不會修改數據庫的數據。默認值為false
rollbackFor 觸發(fā)事務回滾的異常類數組。當方法拋出指定的異常時,事務將回滾。
noRollbackFor 不觸發(fā)事務回滾的異常類數組。當方法拋出指定的異常時,事務將不會回滾。
rollbackForClassName 觸發(fā)事務回滾的異常類名數組。當方法拋出指定的異常時,事務將回滾。
noRollbackForClassName 不觸發(fā)事務回滾的異常類名數組。當方法拋出指定的異常時,事務將不會回滾。
value 用于指定事務管理器的名稱。如果應用程序中存在多個事務管理器,可以使用該參數指定要使用的事務管理器的名稱。默認情況下,事務將使用默認的事務管理器。
transactionManager 用于指定事務管理器的引用??梢灾苯訉⒁粋€事務管理器對象傳遞給該參數,以指定要使用的事務管理器。默認情況下,事務將使用默認的事務管理器。

對于上述表格中的事務隔離級別需要重點掌握,具體后面詳細說。

需要特別注意的是,如果方法中的異常被 try-catch 異常捕獲處理后,則不會再進行事務的回滾。

當然,我們可以通過 throw 將異常拋出,使得事務能夠正常自動回滾。但是這樣子做,try-catch 還有意義嗎?springboot事務級別,JavaEE編程之路,spring,spring boot,后端

因此,對于這種情況,更偏向于使用另一種優(yōu)雅的方式,進行手動回滾事務來解決~

如何在聲明式事務中進行手動回滾事務?
使用代碼進行手動回滾事務:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

示例代碼如下:
springboot事務級別,JavaEE編程之路,spring,spring boot,后端

1.4 @Transactional 的工作原理

  1. 當調用被@Transactional注解標記的方法時,事務管理器會檢查當前是否存在一個事務。如果存在事務,則該方法將在該事務的上下文中執(zhí)行;如果不存在事務,則會創(chuàng)建一個新的事務。
  2. 在方法執(zhí)行期間,如果發(fā)生了受檢查異常(checked exception),事務管理器會捕獲該異常,并根據配置的回滾規(guī)則決定是否回滾事務。如果異常被捕獲并且需要回滾事務,則事務將被回滾,方法的執(zhí)行將終止,并將異常傳播給調用方。
  3. 如果方法成功執(zhí)行并且沒有拋出受檢查異常,事務管理器將提交事務,將數據庫中的更改持久化。
  4. 如果方法執(zhí)行期間拋出了未受檢查異常(unchecked exception)或錯誤(Error),事務管理器會將事務標記為回滾,并將異常傳播給調用方。
  5. 如果方法執(zhí)行期間沒有拋出異常,但在方法內部調用了其他被@Transactional注解標記的方法,事務管理器將根據事務的傳播行為決定如何處理這些方法。例如,如果傳播行為設置為REQUIRED,則內部方法將加入當前事務;如果傳播行為設置為REQUIRES_NEW,則內部方法將創(chuàng)建一個新的事務。

具體來看,@Transactional 是基于 AOP 實現的,AOP ?是使?動態(tài)代理實現的。如果?標對象實現了接?,默認情況下會采? JDK 的動態(tài)代理,如果?標對象沒有實現了接?,會使? CGLIB 動態(tài)代理。@Transactional 在開始執(zhí)?業(yè)務之前,通過代理先開啟事務,在執(zhí)?成功之后再提交事務。如果中途遇到的異常,則回滾事務。實現細節(jié)的執(zhí)行流程如圖所示:
springboot事務級別,JavaEE編程之路,spring,spring boot,后端


2 事務的隔離級別

2.1 事務的四大特性及事務的隔離級別回顧

事務有4 ?特性(ACID),原?性、?致性、隔離性和持久性:

  • 原?性: ?個事務中的所有操作,要么全部完成,要么全部不完成。若事務在執(zhí)?過程中發(fā)?錯誤,會被回滾到事務開始前的狀態(tài)。
  • ?致性: 在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。即寫?的資料必須完全符合所有的預設規(guī)則,這包含資料的精確度、串聯(lián)性以及后續(xù)數據庫可以?發(fā)性地完成預定的?作。
  • 持久性: 事務處理結束后,對數據的修改就是永久的,即便系統(tǒng)故障也不會丟失。
  • 隔離性: 數據庫允許多個并發(fā)事務同時對其數據進?讀寫和修改的能?,隔離性可以防?多個事務并發(fā)執(zhí)?時由于交叉執(zhí)??導致數據的不?致。

其中,對于隔離性有隔離級別可以設置。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串?化(Serializable)。

歸根到底,事務隔離級別的設置是為了防止其它事務影響當前事務的一種策略。

在MySQL中,默認是可重復讀(repeatable read)級別。以下是MySQL常見的事務隔離級別以及它們對臟讀、不可重復讀和幻讀問題的解決情況的表格:

事務隔離級別 臟讀(Dirty Read) 不可重復讀(Non-repeatable Read) 幻讀(Phantom Read)
讀未提交(Read Uncommitted) 可能發(fā)生 可能發(fā)生 可能發(fā)生
讀已提交(Read Committed) 避免 可能發(fā)生 可能發(fā)生
可重復讀(Repeatable Read) 避免 避免 可能發(fā)生
串行化(Serializable) 避免 避免 避免

對于臟讀、不可重復讀和幻讀的解釋:

  • 臟讀(Dirty Read):指一個事務讀取了另一個事務未提交的數據。如果一個事務可以讀取未提交的數據,則會發(fā)生臟讀。

  • 不可重復讀(Non-repeatable Read):指在同一個事務中,多次讀取同一行數據時,得到的結果不一致。這是因為在讀取期間,另一個事務修改了該行數據。

  • 幻讀(Phantom Read):指在同一個事務中,多次查詢同一個范圍的數據時,得到的結果集不一致。這是因為在查詢期間,另一個事務插入或刪除了符合查詢條件的數據。

每個隔離級別對這些問題的解決情況如下:

  • 讀未提交(Read Uncommitted):允許臟讀、不可重復讀和幻讀。一個事務可以讀取另一個事務未提交的數據。

  • 讀已提交(Read Committed):避免臟讀。一個事務只能讀取已提交的數據。但是,可能發(fā)生不可重復讀和幻讀,因為在同一個事務中,另一個事務可能會修改數據。

  • 可重復讀(Repeatable Read):避免臟讀和不可重復讀。在同一個事務中,多次讀取同一行數據時,得到的結果是一致的。但是,可能發(fā)生幻讀,因為在同一個事務中,另一個事務可能會插入或刪除數據。

  • 串行化(Serializable):避免臟讀、不可重復讀和幻讀。事務串行執(zhí)行,保證了數據的一致性和完整性。

但隔離級別的提升會增加并發(fā)性能的開銷,因為更高的隔離級別通常需要使用鎖來實現。

在數據庫中,可以使用如下語句來查詢全局事務隔離級別和當前連接的事務隔離級別:

select @@global.tx_isolation,@@tx_isolation;

springboot事務級別,JavaEE編程之路,spring,spring boot,后端

2.2 Spring 事務的隔離級別及設置

在Spring框架中,事務的隔離級別可以使用@Transactional注解來設置。@Transactional注解可以應用在方法級別或類級別上,用于聲明一個事務性方法或類。

Spring 框架支持以下五個事務隔離級別:

  1. DEFAULT(默認):使用底層數據庫的默認隔離級別。對于大多數數據庫來說,通常是READ_COMMITTED

  2. READ_UNCOMMITTED:讀未提交。允許臟讀、不可重復讀和幻讀。這是最低的隔離級別,一個事務可以讀取另一個事務未提交的數據。

  3. READ_COMMITTED:讀已提交。避免臟讀。一個事務只能讀取已提交的數據。但是,可能發(fā)生不可重復讀和幻讀,因為在同一個事務中,另一個事務可能會修改數據。

  4. REPEATABLE_READ:可重復讀。避免臟讀和不可重復讀。在同一個事務中,多次讀取同一行數據時,得到的結果是一致的。但是,可能發(fā)生幻讀,因為在同一個事務中,另一個事務可能會插入或刪除數據。

  5. SERIALIZABLE:串行化。避免臟讀、不可重復讀和幻讀。事務串行執(zhí)行,保證了數據的一致性和完整性,但是性能太低。

可以在@Transactional注解上使用isolation屬性來設置事務的隔離級別。例如:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void myTransactionalMethod() {
    // 事務性操作
}

需要注意的是,事務的隔離級別還受數據庫本身支持的隔離級別的限制。如果數據庫不支持某個特定的隔離級別,那么Spring框架將盡力使用最接近的隔離級別。


3 Spring 事務傳播機制

3.1 初探事務的傳播機制

事務的傳播機制是用來定義事務在傳播過程中的行為模式的一種機制。 Spring 事務傳播機制定義了多個包含了事務的方法,相互調用時,事務是如何在這些方法進行傳遞的。

對比事務的隔離級別來看,如果說事務的隔離級別是保證多個并發(fā)事務執(zhí)行的可控性的(穩(wěn)定性),則 事務的傳播機制就是保證一個事務在多個調用方法間的可控性的(穩(wěn)定性)。

事務的隔離級別解決的是多個并發(fā)事務調用數據庫的問題:
springboot事務級別,JavaEE編程之路,spring,spring boot,后端

事務的傳播機制解決的是一個事務在多個節(jié)點(方法)中傳遞的問題:
springboot事務級別,JavaEE編程之路,spring,spring boot,后端
比如,方法 A 正常執(zhí)行,完成了事務。但是,方法 B 發(fā)生了錯誤。那么,方法 A 進行的事務操作是否要回滾呢?這就是事務的傳播機制需要解決的問題~

3.2 Spring 事務傳播機制的分類及設置

在Spring框架中,事務傳播機制用于定義在多個事務性方法相互調用時,事務如何傳播和交互的規(guī)則。Spring框架提供了七種不同的事務傳播行為:

  1. REQUIRED(需要有):如果當前存在事務,則加入該事務;如果當前沒有事務,則創(chuàng)建一個新的事務。這是最常用的傳播行為。

  2. SUPPORTS(可以有):如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務方式執(zhí)行。

  3. MANDATORY(強制有):如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。

  4. REQUIRES_NEW:創(chuàng)建一個新的事務,并掛起當前事務(如果存在)。新創(chuàng)建的事務與當前事務完全獨立。

  5. NOT_SUPPORTED:以非事務方式執(zhí)行,并且掛起當前事務(如果存在)。

  6. NEVER:以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。

  7. NESTED:如果當前存在事務,則在嵌套事務中執(zhí)行。嵌套事務是獨立于當前事務的子事務,它可以獨立地進行提交或回滾。如果當前沒有事務,則創(chuàng)建一個新的事務。

這些事務傳播行為可以通過@Transactional注解的propagation屬性進行設置。例如:

@Transactional(propagation = Propagation.REQUIRED)
public void myTransactionalMethod() {
    // 事務性操作
}

需要注意的是,事務傳播行為僅在方法之間的調用時才會生效,對于同一個方法內部的事務性操作,傳播行為不會起作用。

如果將事務比作房子,以伴侶為例子理解(以下圖片來自網絡):
springboot事務級別,JavaEE編程之路,spring,spring boot,后端

3.3 嵌套事務(NESTED)和加入事務(REQUIRED )的區(qū)別

  1. 整個事務如果全部執(zhí)行成功,二者的結果是一樣的。
  2. 如果事務執(zhí)行到一半失敗了,那么加入事務整個事務會全部回滾;而嵌套事務會局部回滾,不會影響上一個方法中執(zhí)行的結果。

寫在最后

?本文被 JavaEE編程之路 收錄點擊訂閱專欄 , 持續(xù)更新中。
?以上便是本文的全部內容啦!創(chuàng)作不易,如果你有任何問題,歡迎私信,感謝您的支持!

springboot事務級別,JavaEE編程之路,spring,spring boot,后端文章來源地址http://www.zghlxwxcb.cn/news/detail-635688.html

到了這里,關于【Spring Boot】事務的隔離級別與事務的傳播特性詳解:如何在 Spring 中使用事務?不同隔離級別的區(qū)別?的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【JavaEE】Spring事務-@Transactional參數介紹-事務的隔離級別以及傳播機制

    【JavaEE】Spring事務-@Transactional參數介紹-事務的隔離級別以及傳播機制

    【JavaEE】Spring 事務(2) 參數 作用 value 當配置了多個事務管理器時,可以使用該屬性指定選擇哪個事務管理器 transactionManager 當配置了多個事務管理器時,可以使用該屬性指定選擇哪個事務管理器 isolation 事務的隔離級別.默認值為solation.DEFAULT propagation 事務的傳播機制,默認值

    2024年02月10日
    瀏覽(26)
  • Spring事務的四大特性+事務的傳播機制+隔離機制

    Spring事務的四大特性+事務的傳播機制+隔離機制

    原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發(fā)生,要么都不發(fā)生。 事務是一個原子操作, 由一系列動作組成。 組成一個事務的多個數據庫操作是一個不可分割的原子單元 ,只有所有的操作執(zhí)行成功,整個事務才提交。 事務中的任何一個數據庫操作失敗

    2024年01月20日
    瀏覽(32)
  • 聊一聊數據庫事務的那些事(隔離級別,傳播行為)

    聊一聊數據庫事務的那些事(隔離級別,傳播行為)

    ? 我們平時使用事務的時候,可能腦子里面想到和事務有關的知識點無非就是,ACID,事務隔離級別那一套,使用的事務也就是是通過注解的形式,或者手動開啟事務。更細致一點的問題或許沒有深究下去,比如事務的傳播行為,注解形式和手動事務的區(qū)別等,今天我們就這幾

    2024年02月07日
    瀏覽(22)
  • MySQL的事務特性、事務特性保證和事務隔離級別

    ????????事務是指要么所有的操作都成功執(zhí)行,要么所有的操作都不執(zhí)行的一組數據庫操作。 一、MySQL提供了四個事務特性,即ACID: ??? ?????1. 原子性(Atomicity) :一個事務中的所有操作要么全部提交成功,要么全部回滾失敗,保證事務的原子性。 ??????? ?2. 一

    2024年02月03日
    瀏覽(22)
  • 事務——什么是事務,事務的特性,事務的隔離級別

    ????????事務就是用戶定義的一系列操作,這些操作可以視為一個完成的邏輯處理工作單元,要么全部執(zhí)行,要么全部不執(zhí)行,是不可分割的工作單元。 典型場景:銀行轉賬 A 轉賬100元給B,A賬戶減少100元,B賬戶增加100元; 如果A轉出失敗或者B轉入失?。ㄈ我庖环绞。?/p>

    2024年02月10日
    瀏覽(25)
  • 58、事務的基本特性和隔離級別

    事務基本特性ACID分別是: 原子性 指的是一個事務中的操作要么全部成功,要么全部失敗。 一致性 指的是數據庫總是從一個一致性的狀態(tài)轉換到另外一個一致性的狀態(tài)。比如A轉賬給B 100塊錢,假設A只有90塊,支付之前我們數據庫里的數據都是符合約束的,但是如果事務執(zhí)行成功

    2024年02月16日
    瀏覽(20)
  • javaee 事務 事務的特性 事務的并發(fā)問題 事務的隔離級別

    是并發(fā)控制的單元,是用戶定義的一個操作序列。這些操作要么都做,要么都不做,是一個不可分割的工作單位。通過事務,sql 能將邏輯相關的一組操作綁定在一起,以便服務器 保持數據的完整性。事務通常是以begin/start transaction開始,以commit或rollback結束。Commint表示提交,

    2024年02月09日
    瀏覽(28)
  • 數據庫事務的四大特性與事務的隔離級別

    數據庫事務的四大特性與事務的隔離級別

    概要: 事務的四個特性:原子性、一致性、隔離性、持久性 事務不隔離帶來的問題:更新丟失、臟讀、不可重復讀、虛讀(幻讀)。其中更新丟失就是并發(fā)寫,這是一定不允許的,因此一定要解決更新丟失問題。 事務隔離的級別:讀未提交(1000)、讀已提交(1100)、可重

    2023年04月09日
    瀏覽(28)
  • Spring事務隔離級別

    Spring事務隔離級別共有五種:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATBLE_READ、SERIALIZABLE。下面對這五個級別進行簡單的介紹。 1 DEFAULT Spring中 默認 的事務隔離級別。以連接的數據庫的事務隔離級別為準。 2 READ_UNCOMMITTED Spring事務 最弱 的隔離級別。一個事務可以讀取到另一個

    2024年02月09日
    瀏覽(18)
  • Spring的事務隔離級別

    Spring的事務隔離級別是用于控制事務并發(fā)訪問數據庫時的行為。Spring框架提供了五個事務隔離級別,分別是: 1. DEFAULT(默認):使用數據庫默認的事務隔離級別。在大多數情況下,這等同于使用READ_COMMITTED級別。 2. READ_UNCOMMITTED(讀取未提交數據):最低的隔離級別,允許一

    2024年02月09日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包