資料庫事務的四種隔離機制和七種傳播行為
MySQL資料庫為我們提供的四種隔離級別:(依次解決髒讀、不可重複讀、幻讀)
① Serializable (序列化):可避免髒讀、不可重複讀、幻讀的發生。
② Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。(Mysql預設的方式)
③ Read committed (讀已提交):可避免髒讀的發生。(Oracle預設的方式)
④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。(INNODB內部機制)
資料庫事務正常執行的四個特性:
ACID屬性:
原子性(atomicity):即不可分割,事務要麼全部被執行,要麼全部不執行
一致性(consistency):事務的執行使得資料庫從一種正確狀態轉換成另外一種正確狀態
隔離性(isolation):在事務正確提交之前,不允許把事務對該資料的改變提供給任何其他事務
永續性(durability):事務正確提交之後,其結果將永遠儲存在資料庫之中,即使在事務提交之後有了其他故障,事務的處理結果也會得到儲存
併發下事務產生的問題:
1、髒讀:事務A讀到了事務B還沒有提交的資料;
2、不可重複讀:在一個事務裡面讀取了兩次某個資料,讀出來的資料不一致;
3、幻讀:在一個事務裡面的操作中發現了未被操作的資料。
幻讀,需要應用使用加鎖讀來保證。而這個加鎖度使用到的機制就是next-key locks。
SELECT * FROM t_bitfly LOCK IN SHARE MODE;
SELECT * FROM t_bitfly FOR UPDATE;(重複讀,看到其他事物提交的資料)。
Read uncommitted - 讀不需要加鎖,寫僅僅需要加 行鎖。 Read committed - 需要加 寫鎖,讀必須等待寫事務結束。避免髒讀 Repeatable reads - 需要加 讀鎖,當有事務在讀一行記錄,其他寫同一行的事務都會阻塞。避免不可重複讀。 Serializable - 需要加 範圍鎖,當有事務 SELECT 某個範圍的資料時,其他訪問同一範圍的事務都會阻塞。避免幻讀。
Oracle資料庫中:
Serializable (序列化)級別。
Read committed (讀已提交)這兩種級別,其中預設的為Read committed級別。
在MySQL資料庫中檢視當前事務的隔離級別:
select @@tx_isolation;
在MySQL資料庫中設定事務的隔離 級別:
set [glogal | session] transaction isolation level 隔離級別名稱; set tx_isolation=’隔離級別名稱;’
事務傳播行為型別 |
說明 |
PROPAGATION_REQUIRED |
如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是 最常見的選擇。 |
PROPAGATION_SUPPORTS |
支援當前事務,如果當前沒有事務,就以非事務方式執行。 |
PROPAGATION_MANDATORY |
使用當前的事務,如果當前沒有事務,就丟擲異常。 |
PROPAGATION_REQUIRES_NEW |
新建事務,如果當前存在事務,把當前事務掛起。 |
PROPAGATION_NOT_SUPPORTED |
以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 |
PROPAGATION_NEVER |
以非事務方式執行,如果當前存在事務,則丟擲異常。 |
PROPAGATION_NESTED |
如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與 PROPAGATION_REQUIRED 類似的操作。 |