事物隔離級別

2021-09-19 05:24:36 字數 2929 閱讀 3977

事務隔離級別:

1.更新遺失(lost update)

兩個事務都同時更新一行資料,但是第二個事務卻中途失敗退出,導致對資料的兩個修改都失效了。這是因為系統沒有執行任何的鎖操作,因此併發事務並沒有被隔離開來。

基本上就是指某個事務對欄位進行更新的資訊,因另乙個事務的介入而遺失更新效力。舉例來說,若某個字段資料原為zzz,使用者a、b 分別在不同的時間點對同一字段進行更新事務,如下圖:

單就使用者a 的事務而言,最後字段應該是ooo,單就使用者b 的事務而言,最後字段應該是zzz。在完全沒有隔離兩者事務的情況下,由於使用者b 撤銷操作時間在使用者a 確認之後,因此最後字段結果會是zzz,使用者a看不到他新確認的ooo 結果,使用者a 發生更新遺失問題。

如果要避免更新遺失問題,需要設定隔離級別為「可讀取未確認」(read uncommitted),如果乙個事務已經開始寫資料,則另外乙個資料則不允許同時進行寫操作,但允許其他事務讀此行資料。

該隔離級別可通過「排他寫鎖」實現。jdbc 可通過connection 的settransactionisolation()設定為transaction_uncommitted 來提示資料庫指定此隔離行為。

實現後如下圖:

提示資料庫「可讀取未確認」的隔離層次之後,資料庫至少得保證事務能避免更新遺失問題,通常這也是具備事務功能的資料庫引擎會採取的最低隔離層級。不過這個隔離層級讀取錯誤資料的機率太高,一般預設不會採用這種隔離級別。

2.髒讀(dirty read)

兩個事務同時進行,其中乙個事務更新資料但未確認,另乙個事務就讀取資料,就有可能發生髒讀問題,也就是讀到所謂髒資料、不乾淨、不正確的資料。如下圖:

如果要避免髒讀問題,可以設定隔離層級為「可讀取確認」(read committed)。這可以通過「瞬間共享讀鎖」和「排他寫鎖」實現。讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行。也就是事務讀取的資料必須是其他事務已確認的資料。jdbc 可通過connection 的settransactionisolation()設定為transaction_committed 來提示資料庫指定此隔離行為。

實現後如下圖所示:

提示資料庫「可讀取確認」的隔離層次之後,資料庫至少得保證事務能避免髒讀與更新遺失問題。

3.無法重複的讀取(unrepeatable read)

某個事務兩次讀取同一欄位的資料並不一致。如下圖:

如果要避免無法重複的讀取問題, 可以設定隔離層級為「可重複讀取」(repeatable read),這可以通過「共享讀鎖」和「排他寫鎖」實現。讀取資料的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。也就是同一事務內兩次讀取的資料必須相同。jdbc 可通過connection 的settransactionisolation()設定為transaction_repeatable_read 來提示資料庫指定此隔離行為。

實現後如下圖所示:

在資料庫上這個做法影響效能較大,另乙個基本做法是事務正在讀取但尚未確認前,另一事務會在暫存**上更新。提示資料庫「可重複讀取」的隔離層次之後,資料庫至少得保證事務能避免無法重複讀取、髒讀與更新遺失問題。

4.幻讀(phantom read)

同一事務期間,讀取到的資料筆數不一致。例如,事務a 第一次讀取得到五筆資料,此時事務b 新增了一筆資料,導致事務b 再次讀取得到六筆資料。

如果隔離行為設定為可重複讀取,但發生幻讀現象,可以設定隔離層級為「可循序」(serializable),它要求事務序列化執行,事務只能乙個接著乙個地執行,但不能併發執行。如果僅僅通過「行級鎖」是無法實現事務序列化的,必須通過其他機制保證新插入的資料不會被剛執行查詢操作的事務訪問到。也就是在有事務時若有資料不一致的疑慮,事務必須可以按照順序逐一進行。jdbc 可通過connection 的settransactionisolation()設定為transaction_serializable 來提示資料庫指定此隔離行為。

隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為read committed。它能夠避免髒讀取,而且具有較好的併發效能。儘管它會導致不可重複讀、虛讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖或樂觀鎖來控制。

下面是隔離行為與可預防的問題

隔離行為

更新遺失

髒讀無法重複讀取

幻讀可讀取未確認read uncommitted

預防可讀取確認

read uncommitted

預防預防

可重複讀取

repeatable read

預防預防

預防可循序

serializable

預防預防

預防預防

資料庫事務的acid特性:

1. 原子性(atomicity)

整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

例如:銀行刷卡業務,當消費的時候a顧客的卡錢減少,然後b**的賬戶加錢,只有當這2個操作都成功的時候才可以進行提交,否則都必須回滾。這就是事務的原子性,因為這2個操作不可以分開。

2. 一致性(consistency)

在事務開始之前和事務結束以後,資料庫的完整性約束沒有被破壞。

例如:有表a和表b,表a中的乙個欄位aa是表b中bb欄位的外來鍵,並且bb欄位是必填的,當在b表中插入資料的時候如果bb欄位的值在a表中沒有,則事務必須回滾否則會破壞資料庫的完整性約束。

3. 隔離性(isolation)

兩個事務的執行是互不干擾的,乙個事務不可能看到其他事務執行時,中間某一時刻的資料。

例如:a顧客銀行卡刷的錢與b顧客互相不影響。

4. 永續性(durability)

在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾。

例如:在a顧客消費成功後,銀行卡的錢不可以被回滾。

事物隔離級別

自然也是支援四種事務隔離級別的 read uncommitted,read commit,repeatable read serializable,下面就分別最四種隔離級別在實現的鎖機制做乙個簡介 serializable 1 這種隔離級別對資料的要求最為嚴格,自然也是效能最差的一種隔離級別。在所有...

事物隔離級別

隔離級別從松到緊 讀未提交,讀提交 重複讀,序列化。讀未提交 可能會出現髒讀的情況 例子 你去買5個包子。人多。店員拿的急多方乙個,袋子裡有6個,這個時候,你眼睛一瞟。心裡美滋滋。付錢的時候老闆檢查了一下,發現多了乙個,就拿走了乙個,然後你付錢走人 提交事務 這時候你就發現實際上袋子裡只有5個,但是...

事物隔離級別

在分布式的系統中,通常會有多個執行緒連線到資料庫中同時對乙個表進行操作 這裡的同時並不表示同乙個時間點,而是同時競爭cpu的資源,至於如何排程,就要看執行緒和作業系統如何進行排程了 這種情況下如果會話的事物設定不當,就會導致資料混亂,常常會出現以下三種情況 假設現在系統中有兩個會話a和b,同時對錶t...