您的位置:首頁技術文章
文章詳情頁

帶大家深入了解Spring事務

瀏覽:3日期:2022-08-12 17:55:31
目錄一、數據庫事務簡介二、事務的特性三、事務的隔離級別四、Spring事務五、PlatformTransactionManager簡介六、Spring事務隔離級別和傳播級別一、數據庫事務簡介

構成單一邏輯工作單元的操作集合稱作事務(transaction)。即使有故障,數據庫系統也必須保證事務的正確執行——要么執行整個事務,要么屬于該事務的操作一個也不執行。以資金轉賬為例,應該保證支票賬戶支出金額的操作和儲蓄賬戶的存入金額的操作在同一個邏輯工作單元內完成。簡言之,事務是訪問并可能更新各種數據項的一個程序執行單元(unit)。

二、事務的特性

數據庫需要維護事務的以下四個性質:

1.原子性(Atomicity)事務是一個原子操作,由一系列動作組成。事務的原子性確保這一系列動作要么全部完成,要么完全不起作用。

2.一致性(Consistency)隔離執行事務時(在沒有其他事務并發的情況下),保持數據庫的一致的數據庫狀態。

3.隔離性(Isolation)并發事務執行之間無影響,在一個事務內部的操作對其他事務是不產生影響,這需要事務隔離級別來指定隔離性。每個事務都感覺不 到系統中其他事務在并發地執行。

4.持久性(Durability)一旦事務完成,數據庫的改變必須是永久的,即使出現系統故障。

三、事務的隔離級別

在實際應用中,數據庫中的數據是要被多個用戶共同訪問的,在多個用戶同時操作相同的數據時,可能就會出現一些事務并發的問題:

1.臟讀(Dirty Read)。一個事務讀取到另一個事務未提交的數據。

2.不可重復讀(Non-repeatable Read)。一個事務對同一行數據重復讀取兩次,但得到的結果不同。

3.虛讀/幻讀(Phantom Read)。一個事務執行兩次查詢,但第二次查詢的結果包含了第一次查詢中未出現的數據。

4.丟失更新(Lost Update)。丟失更新可分為兩類,分別是第一類丟失更新和第二類丟失更新。第一類丟失更新是指兩個事務同時操作同一個數據時,當第一個事務撤銷時,把已經提交的第二個事務的更新數據覆蓋了,第二個事務就造成了數據丟失。第二類丟失更新是指當兩個事務同時操作同一個數據時,第一個事務將修改結果成功提交后,對第二個事務已經提交的修改結果進行了覆蓋,對第二個事務造成了數據丟失。

為了避免上述事務并發問題的出現,在標準的 SQL 規范中定義了四種事務隔離級別,不同的隔離級別對事務的處理有所不同:

1.Serializable(可串行化)提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接一個地執行,不能并發執行。此隔離級別可有效防止臟讀、不可重復讀、幻讀。但這個級別可能導致大量的超時現象和鎖競爭,在實際應用中很少使用。

2.Repeatable Read(可重復讀)一個事務在執行過程中,可以訪問其他事務成功提交的新插入的數據,但不可以訪問成功修改的數據。讀取數據的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。此隔離級別可有效防止不可重復讀和臟讀。

3.Committed Read(已提交讀)一個事務在執行過程中,既可以訪問其他事務成功提交的新插入的數據,又可以訪問成功修改的數據。讀取數據的事務允許其他事務繼續訪問該行數據,但是未提交的寫事務將會禁止其他事務訪問該行。此隔離級別可有效防止臟讀。

4.Uncommitted Read(未提交讀)一個事務在執行過程中,既可以訪問其他事務未提交的新插入的數據,又可以訪問未提交的修改數據。如果一個事務已經開始寫數據,則另外一個事務不允許同時進行寫操作,但允許其他事務讀此行數據。此隔離級別可防止丟失更新。以上所有隔離性級別都不允許臟寫(Dirty Write)。

一般來說,事務的隔離級別越高,越能保證數據庫的完整性一致性,但相對來說,隔離級別越高,對并發性能的影響也越大。因此,通常將數據庫的默認隔離級別設置為已提交讀 (Committed Read),它既能防止臟讀,又能有較好的并發性能。雖然這種隔離級別會導致不可重復讀、幻讀和第二類丟失更新這些并發問題,但可通過在應用程序中采用悲觀鎖或樂觀鎖加以控制。

四、Spring事務

Spring事務的本質就是數據庫對事務的支持,使用JDBC的事務管理機制,利用java.sql.Connection對象完成對事務的提交,未使用Spring框架前,Java中事務實現示例代碼如下:

package com.example.demo;import java.sql.Connection;import java.sql.DriverManager;public class DemoApplication { public static void main(String[] args) {// 1.獲取連接Connection conn = DriverManager.getConnection();try { // 2.將自動提交設置為false conn.setAutoCommit(false); /*-----------------*/ // 3.執行一到多個CRUD操作 /*-----------------*/ // 4.1手動提交 conn.commit();} catch (Exception e) { // 4.2一旦其中一個操作出錯都將回滾,所有操作都不成功 conn.rollback();} finally { // 5.關閉連接 conn.colse();} }}

Spring框架則提供統一的事務抽象,無論是JTA、JDBC、Hibernate/JPA、Mybatis/Mybatis-Plus,Spring都使用統一的編程模型,使得應用程序可以很容易地在不同的事務框架之間進行切換。這也符合面向接口編程思想。Spring事務框架的代碼在org.springframework:spring-tx中。Spring事務抽象的核心類圖如下:

帶大家深入了解Spring事務

Spring事務管理的核心接口是PlatformTransactionManager。接口PlatformTransactionManager定義事務操作的行為,PlatformTransactionManager依賴TransactionDefinition和TransactionStatus接口。TransactionDefinition接口定義與Spring兼容的事務屬性(如隔離級別、事務傳播行為等)。TransactionStatus接口則定義事務的狀態(如是否回滾、是否完成、是否包含安全點(Save Point)、將基礎會話刷新到數據存儲區(如果適用)等)。

五、PlatformTransactionManager簡介

PlatformTransactionManager是Spring事務框架的核心接口。應用程序可以直接使用PlatformTransactionManager,但它并不是主要用于API:應用程序將借助事務模板(TransactionTemplate)或聲明式事務(Declarative Transaction)。對于需要實現PlatformTransactionManager接口的應用程序,可通過繼承AbstractPlatformTransactionManager抽象類的方式實現。AbstractPlatformTransactionManager類已實現事務傳播行為和事務同步處理。子類需要實現針對事務特定狀態(如:begin,suspend,resume,commit)的模板方法。Spring事務框架已經實現了JtaTransactionManager(JPA)和DataSourceTransactionManager(JDBC)。應用程序可以參考以上方法實現事務管理器。PlatformTransactionManager事務繼承示例如下:

帶大家深入了解Spring事務

六、Spring事務隔離級別和傳播級別

TransactionDefinition接口中定義了Spring事務隔離級別和Spring事務傳播級別。隔離級別主要控制事務并發訪問時隔離程度。Spring支持的隔離級別如下:

帶大家深入了解Spring事務

除了使用ISOLATION_DEFAULT表示使用數據庫默認的隔離級別外,其余四個隔離級別與數據庫規范的隔離級別一致。需要注意的是,隔離級別越高,意味著數據庫事務并發執行性能越差。JDBC規范雖然定義了事務支持的以上行為,但是各個JDBC驅動、數據庫廠商對事務的支持程度可能各不相同。出于性能的考慮我們一般設置READ_COMMITTED級別。針對READ_COMMITTED隔離級別無法避免的臟讀,通常使用數據庫的鎖來處理。傳播級別主要控制含事務方法的調用(如一個事務方法調用另一個事務方法)時,Spring對事務的處理方式。Spring事務傳播級別共七類。它們是:

(1)PROPAGATION_REQUIRED:支持當前事務,如果當前有事務則加入,如果當前沒有事務則新建一個。這種方式是默認的事務傳播方式。

(2)PROPAGATION_SUPPORTS:支持當前事務,如果當前有事務則加入,如果當前沒有事務則以非事務方式執行。

(3)PROPAGATION_MANDATORY:支持當前事務,如果當前有事務則加入,如果當前沒有事務則拋出異常。(當前必須有事務)

(4)PROPAGATION_REQUIRES_NEW:支持當前事務,如果當前有事務則掛起當前事務,然后新創建一個事務,如果當前沒有事務則自己創建一個事務。

(5)Propagation_NOT_SUPPORTED:不支持當前事務,如果當前有事務則把當前事務掛起,執行完后恢復事務(忽略當前事務)。

(6)PROPAGATION_NEVER:不支持當前事務,如果當前存在事務,則拋出異常。(當前必須不能有事務)

(7)PROPAGATION_NESTED:如果當前存在事務,則嵌套在當前事務中。如果當前沒有事務,則新建一個事務自己執行。對嵌套事務來說,內部事務回滾時不會影響外部事務的提交;但是外部事務回滾會把內部事務一起回滾回去。(這個和新建一個事務的區別)

到此這篇關于帶大家深入了解Spring事務的文章就介紹到這了,更多相關Spring事務內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
国产综合久久一区二区三区