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

1.簡介

1.1.事務是什麼

事務(Transaction)是由一條或多條操作數據庫的 SQL 語句組成的一個不可分割的工作單元,這些操作要麼都完成,要麼都回滾。一個事務往往對應一個完整的業務。

1.2.事務關鍵流程

2.事務四大特性(ACID)

2.1.原子性(atomicity)

事務是個完整體,不可再分(就像化學中的原子不可再分),要求所有DML語句操作必須同時成功或同時失敗。

2.2.一致性(consistency)

事務前後的數據要保持一致。
如:A有10元錢,B有20元錢。B轉10元給A,完成轉賬後A+B的錢還是30元。

2.3.隔離性( isolation )

不同的事務之間互相隔離。

2.4.持久性(durability)

事務結束後,內存數據持久化的磁盤中。

3.並發問題

3.1.兩種數據丟失

第一種是指兩個事務同時操作同一個數據時,當第一個事務回滾時,把已經提交的第二個事務的更新數據覆蓋了,第二個事務就造成了數據丟失。

第二種是指當兩個事務同時操作同一個數據時,第一個事務將修改結果成功提交後,對第二個事務已經提交的修改結果進行了覆蓋,對第二個事務造成了數據丟失。

3.2.臟讀

臟讀是指一個事務讀取了另一個未提交事務的數據。

如:事務A讀取了事務B未提交的數據,假如事務B未正確執行,回滾,則事務A讀取到的就是臟數據。

問題關鍵點:讀了未提交事務的數據。

3.3.不可重複讀

不可重複讀是指一個事務對同一行數據重複讀取兩次,但得到的結果內容不同。

如:一個事務執行過程中,另一事務提交並修改了當前事務正在讀取的數據

問題關鍵點:同一個事務多次讀條件相同的數據,其他事務還可以修改該條件下的數據。

3.4.幻讀

幻讀是同一個事務的相同的兩次查詢的結果數不一致。

如:一個事務執行過程中,另一個事務新增或刪除了數據,導致兩次相同的查詢結果條數不同。

問題關鍵點:同一個事務多次讀條件相同的數據,其他事務還可以新增或刪除該條件下的數據。

解決問題👇

4.隔離級別

事務分為兩種:讀事務和寫事務。

4.1.讀未提交(Read UnCommitted)

  • 多個事務能同時讀未提交的數據
  • 一個事務讀的時候其他事務還可以寫
  • 一個事務寫的時候其他事務還可以讀
  • 但不能同時寫

解決的問題:可防止丟失更新

4.2.讀已提交(Read Committed)

  • 多個事務能同時讀已提交的數據
  • 一個事務讀的時候其他事務還可以寫
  • 一個事務寫的時候其他事務禁止所有操作
  • 但不能同時寫

解決的問題:可有效防止臟讀。

4.3.可重複讀(Repeatable Read)

  • 多個事務能同時讀已提交的插入數據,不能讀已提交的修改數據
  • 一個事務讀的時候其他事務只能讀禁止寫
  • 一個事務寫的時候其他事務禁止所有操作
  • 但不能同時寫

解決的問題:可有效防止不可重複讀和臟讀(InnoDB存儲引擎還解決了幻讀問題)。

4.4.串行化(Serializable)

  • 事務只能一個接着一個地執行,不能並發執行。

解決的問題:可有效防止臟讀、不可重複讀和幻讀。

但這個級別可能導致大量的超時現象和鎖競爭,在實際應用中很少使用。
img

5.事務的一些常用操作

5.1.設置事務自動提交

--查看當前會話
show session variables like 'autocommit';
--查看全局會話
show global variables like 'autocommit';
--設置當前會話
set session autocommit = 0|1|ON|OFF;
--設置全局會話
set global autocommit = 0|1|ON|OFF;

選項:0|1|ON|OFF

  • 關閉:0 和 OFF
  • 開啟:1 和 ON

5.2.設置隔離級別

--查看當前會話
select @@tx_isolation;
select @@session.tx_isolation;
--查看全局會話
select @@global.tx_isolation;
show global variables like 'tx_isolation';
--設置當前會話
set tx_isolation='隔離級別';
--設置全局會話
set global transaction isolation level 隔離級別;

隔離級別

  • read uncommitted
  • read committed
  • repeatable read
  • serializable

6.總結

一般來說,事務的隔離級別越高,越能保證數據庫的完整性和一致性,但相對來說,隔離級別越高,對並發性能的影響也越大。官方默認使用可重複讀(Repeatable Read) 但也可以將數據庫的隔離級別設置為讀已提交(Read Committed),即能防止臟讀,又能有較好的並發性能,關於不可重複讀、幻讀和第二類數據丟失這些並發問題,可通過在應用程序中採用悲觀鎖和樂觀鎖加以控制。

關注閱讀更多優質文章👇 獲取思維導圖👆公眾號輸入:dt0010