事務的特性和隔離級別

2022-08-09 14:21:25 字數 3977 閱讀 3440

事務特性

原子性(atomicity)

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,

一致性(consistency)

一致性是指事務必須使資料庫從乙個一致性狀態變換到另乙個一致性狀態,也就是說乙個事務執行之   前和執行之後都必須處於一致性狀態。

隔離性(isolation)

隔離性是當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每乙個使用者開啟的事務,不   能被其他事務的操作所干擾,多個併發事務之間要相互隔離。

永續性(durability)

永續性是指乙個事務一旦被提交了,那麼對資料庫中的資料的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作。

不考慮事務的隔離性,會發生的幾種問題

不考慮事務的隔離性會發生以下情況:

1、髒讀:事務a讀取了事務b更新的資料,然後b回滾操作,那麼a讀取到的資料是髒資料

2、不可重複讀:事務 a 多次讀取同一資料,事務 b 在事務a多次讀取的過程中,對資料作了更新並提交,導致事務a多次讀取同一資料時,結果 不一致。

3、幻讀:系統管理員a將資料庫中所有學生的成績從具體分數改為abcde等級,但是系統管理員b就在這個時候插入了一條具體分數的記錄,當系統管理員a改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。

事務的隔離級別:

資料庫預設隔離級別:rr(repeatable read,可重複讀),mvcc主要適用於mysql的rc,rr隔離級別

mvcc用版本號來隔離重複讀寫,實際是一種樂觀鎖避免兩個使用者同時讀同一資料,同時改庫存問題引發超賣問題。

現在來看看

mysql

資料庫為我們提供的四種隔離級別:

① serializable (

序列化)

:可避免髒讀、不可重複讀、幻讀的發生。

② repeatable read (

可重複讀

):可避免髒讀、不可重複讀的發生。

③ read committed (

讀已提交

):可避免髒讀的發生。

④ read uncommitted (

讀未提交

):最低級別,任何情況都無法保證。

然後是關於資料庫的各種鎖的總結:

1.共享鎖(又稱讀鎖)、排它鎖(又稱寫鎖):

innodb引擎的鎖機制:innodb支援事務,支援行鎖和表鎖用的比較多,myisam不支援事務,只支援表鎖。

共享鎖(s):允許乙個事務去讀一行,阻止其他事務獲得相同資料集的排他鎖。

排他鎖(x):允許獲得排他鎖的事務更新資料,阻止其他事務取得相同資料集的共享讀鎖和排他寫鎖。

意向共享鎖(is):事務打算給資料行加行共享鎖,事務在給乙個資料行加共享鎖前必須先取得該錶的is鎖。

意向排他鎖(ix):事務打算給資料行加行排他鎖,事務在給乙個資料行加排他鎖前必須先取得該錶的ix鎖。

說明:1)共享鎖和排他鎖都是行鎖,意向鎖都是表鎖,應用中我們只會使用到共享鎖和排他鎖,意向鎖是mysql內部使用的,不需要使用者干預。

2)對於update、delete和insert語句,innodb會自動給涉及資料集加排他鎖(x);對於普通select語句,innodb不會加任何鎖,事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。

共享鎖(s):select * from table_name where ... lock in share mode。

排他鎖(x):select * from table_name where ... for update。

對於鎖定行記錄後需要進行更新操作的應用,應該使用select...for update 方式,獲取排它鎖。(用共享鎖,在讀了之後再寫會阻塞,會導致死鎖)

這裡說說myisam:myisam在執行查詢語句(select)前,會自動給涉及的所有表加讀鎖,在執行更新操作(update、delete、insert等)前,會自動給涉及的表加寫鎖。

3)innodb行鎖是通過給索引上的索引項加鎖來實現的,因此innodb這種行鎖實現特點意味著:只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖!

2.樂觀鎖、悲觀鎖:

悲觀鎖:悲觀鎖,正如其名,它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)

1)使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,採用手動提交事務的方式,因為mysql預設使用autocommit模式,也就是說,當你執行乙個更新操作後,mysql會立刻將結果進行提交。

2)需要注意的是,在事務中,只有select ... for update 或lock in share mode 同一筆資料時會等待其它事務結束後才執行,一般select ... 則不受此影響。對於update、delete和insert語句,innodb會自動給涉及資料集加排他鎖(x)。

3)補充:mysql select…for update的row lock與table lock

使用select…for update會把資料給鎖住,不過我們需要注意一些鎖的級別,mysql innodb預設row-level lock,所以只有「明確」地指定主鍵(或有索引的地方),mysql 才會執行row lock (只鎖住被選取的資料) ,否則mysql 將會執行table lock (將整個資料表單給鎖住)。

樂觀鎖:

樂觀鎖( optimistic locking ) 相對悲觀鎖而言,樂觀鎖假設認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做(一般是回滾事務)。那麼我們如何實現樂觀鎖呢,一般來說有以下2種方式:

1).使用資料版本(version)記錄機制實現,這是樂觀鎖最常用的一種實現方式。何謂資料版本?即為資料增加乙個版本標識,一般是通過為資料庫表增加乙個數字型別的 「version」 欄位來實現。當讀取資料時,將version欄位的值一同讀出,資料每更新一次,對此version值加一。當我們提交更新的時候,判斷資料庫表對應記錄的當前版本資訊與第一次取出來的version值進行比對,如果資料庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認為是過期資料。

2).樂觀鎖定的第二種實現方式和第一種差不多,同樣是在需要樂觀鎖控制的table中增加乙個字段,名稱無所謂,字段型別使用時間戳(timestamp), 和上面的version類似,也是在更新提交的時候檢查當前資料庫中資料的時間戳和自己更新前取到的時間戳進行對比,如果一致則ok,否則就是版本衝突。

總結:兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了效能,所以這種情況下用悲觀鎖就比較合適。

另外,高併發情況下個人認為樂觀鎖要好於悲觀鎖,因為悲觀鎖的機制使得各個執行緒等待時間過長,極其影響效率,樂觀鎖可以在一定程度上提高併發度。

3.表鎖、行鎖

表級鎖(table-level locking):myisam和memory儲存引擎

行級鎖(row-level locking) :innodb儲存引擎

頁面鎖(page-level-locking):bdb儲存引擎

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。

行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

事務的特性和隔離級別

1.原子性 指事務必須是原子工作單元,對於其資料修改,要麼全都執行,要麼全都不執行。2.一致性 指事務在完成時,必須使所有的資料都保持一致狀態。3.隔離性 指由併發事務所做的修改必須與任何其他併發事務所做的修改隔離。4.永續性 指事務完成之後,對於系統的影響具有永久性。事務隔離級別的含義 是否在讀資...

事務的特性和隔離級別

只要跟資料庫打交道,肯定離不開事務,那什麼是事務呢?簡單來說,事務就是要保證一組對資料庫的操作,要麼成功,要麼失敗。對於mysql而言,事務是在引擎層實現的,mysql原生的myisam是不支援事務的,這也是myisam 被innodb取代的原因之一。事務有四種特性,分別是原子性 atomicity...

事務的特性和隔離級別

事務的特性和隔離級別 1.事務的特性 1 原子性 atomicity 原子性是指事務是乙個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。2 一致性 consistency 乙個事務中,事務前後資料的完整性必須保持一致。3 隔離性 isolation 多個事務,事務的隔離性是指多個使用者併...