在dbms中,事務保證了乙個操作序列可以全部執行或者全部不執行(原子性),從乙個狀態撞邊到另外乙個狀態(一致性)。由於事務滿足永續性。所以一旦事務被提交之後,資料就能被持久化下來,又因為事務是滿足隔離性的,所以,當多個事務同時處理同乙個資料的時候,多個事務是互不影響的。所以,在多個事務併發操作的過程中,如果控制不好隔離級別,就可能產生髒讀,不可重複讀或者幻讀等現象
在資料庫事務的acid四個屬性中,隔離性是最放鬆的乙個。可以在資料操作過程中利用資料庫的鎖機制或者多版本併發控制機制獲取更高的隔離等級。但是,隨著資料庫隔離級別的提高,資料的併發能力也有所下降。所以,如何在併發性和隔離性之間做乙個很好的權衡就成了乙個直觀重要的問題。
在軟體開發中,幾乎每類這樣的問題都會有多種最佳實踐來供參考,很多dbms定義了多個不同的「事務隔離等級」來控制鎖的成都和併發能力。
ansi/iso sol定義的標準隔離級別有四種,從高到底依次為:可序列化、可重複讀、提交讀、未提交讀。
1、未提交讀:最低的隔離級別。在這種事務隔離級別下,乙個事務可以讀到另外乙個事務未提交的資料
實現原理:事務在讀資料的時候並未對資料加鎖,事務在修改資料的時候支隊資料增加行級共享鎖
現象:事務1讀取某行記錄時,事務2也能對這行記錄進行讀取、更新(因為事務1並未對資料增加任何鎖)
當事務2對該記錄進行更新時,事務1再次讀取該記錄,能讀到事務2對該記錄的修改版本(因為事務二只增加了共享讀鎖,事務1可以再增加共享讀鎖讀取資料),即使該修改尚未被提交
事務1更新某行記錄時,事務2不能對這行記錄做更新,知道事務1結束。(因為事務1對資料增加了共享讀鎖,事務2不能增加排他寫鎖進行資料的修改)
2、提交讀:在乙個事務修改資料過程中,如果事務還沒提交,其他事務不能讀取該資料
資料庫鎖的情況:
1、事務對當前被讀取的資料加行級共享鎖(當讀到時才加鎖),一旦讀完該行,立即釋放該行級共享鎖
2、事務在更新某資料的瞬間(就是發生更新的瞬間),必須先對其加行級排他鎖,直到事務結束才釋放
現象:1、事務1在讀取某行記錄的整個過程中,事務2都可以對該行記錄進行讀取(因為事務1對該行記錄增加行級共享鎖的情況下,事務2同樣可以對該資料增加共享鎖來讀資料)
2、事務1讀取某行的一瞬間,事務2不能修改該行資料,但是,只要事務1讀取完該行資料,事務2就可以對該行資料進行修改。(事務1在讀取的一瞬間會對資料增加共享鎖,任何其他事務都不能對該行資料增加排他鎖。但是事務1只要讀完該行資料,就會釋放行級共享鎖,一旦鎖釋放,事務2就可以對資料增加排他鎖並修改資料)
3、事務1更新某行記錄時,事務2不能對這行記錄做更新,直到事務1救贖。(事務1在更新資料的時候,會對該行資料增加排他鎖,直到事務結束才會釋放鎖,所以,在事務2沒有提交之前,事務1都不能對資料增加共享鎖進行資料的讀取。所以,提交讀可以解決髒讀的現象)
可重複讀:由於提交讀隔離級別會產生不可重複讀的讀現象。所以,比提交讀更高乙個級別的隔離級別就可以解決不可重複讀的問題。這種隔離級別就叫可重複讀
資料庫鎖情況:
1、事務在讀取某資料的瞬間(就是開始讀取的瞬間),必須先對其加行級共享鎖,直到事務結束才釋放
2、事務在更新某資料的瞬間(就是發生更新的瞬間),必須先對其加行級排他鎖,直到事務結束才釋放
現象:1、事務1在讀取某行記錄的整個過程中,事務2都可以對該行記錄進行讀取(因為事務1對該行記錄增加行級共享鎖的的情況下,事務2同樣可以對該資料增加共享鎖來讀資料)
2、事務1在讀取某行記錄的整個過程中,事務2都不能修改該行資料(事務1在讀取的整個過程會對資料增加共享鎖,直到事務提交才會釋放鎖。所以整個過程中,熱河其他事務都不能對該行資料增加排他鎖。所以,可重複讀能夠解決不可重複讀的現象)
3、事務1更新某行記錄時,事務2不能對這行記錄做更新,直到事務1結束。(事務一在更新資料的時候,會對該行資料增加排他鎖,知道事務結束才會釋放鎖,所以,在事務二沒有提交之前,事務一都能不對資料增加共享鎖進行資料的讀取。所以,提交讀可以解決髒讀
的現象)
可序列化
可序列化(serializable)是最高的隔離級別,前面提到的所有的隔離級別都無法解決的幻讀,在可序列化的隔離級別中可以解決。我們說過,產生幻讀的原因是事務一在進行範圍查詢的時候沒有增加範圍鎖(range-locks:給select 的查詢中使用乙個「where」子句描述範圍加鎖),所以導致幻讀。
資料庫鎖情況
1、事務在讀取資料時,必須先對其加 表級共享鎖 ,直到事務結束才釋放;
2、事務在更新資料時,必須先對其加 表級排他鎖 ,直到事務結束才釋放。
現象:1、事務1正在讀取a表中的記錄時,則事務2也能讀取a表,但不能對a表做更新、新增、刪除,直到事務1結束。(因為事務一對表增加了表級共享鎖,其他事務只能增加共享鎖讀取資料,不能進行其他任何操作)
2、事務1正在更新a表中的記錄時,則事務2不能讀取a表的任意記錄,更不可能對a表做更新、新增、刪除,直到事務1結束。(事務一對表增加了表級排他鎖,其他事務不能對錶增加共享鎖或排他鎖,也就無法進行任何操作)
雖然可序列化解決了髒讀、不可重複讀、幻讀等讀現象。但是序列化事務會產生以下效果:
1.無法讀取其它事務已修改但未提交的記錄。
2.在當前事務完成之前,其它事務不能修改目前事務已讀取的記錄。
3.在當前事務完成之前,其它事務所插入的新記錄,其索引鍵值不能在當前事務的任何語句所讀取的索引鍵範圍中
事務的隔離級別舉例 事務的隔離級別
乙個事務是乙個完整的業務邏輯單元,不能再分,要麼全部執行成功,要麼全部失敗。比如 a給b轉賬100元,a的銀行卡就會少100元,b的銀行卡就會多100元,整個過程要麼全部執行成功,要麼全部失敗。a 原子性。事務是最小的業務邏輯單元。b 一致性。乙個事務必須保證多條dml語句同時成功或失敗。c 隔離性...
事務的隔離級別舉例 JDBC 事務隔離級別
本文總結了 jdbc 事務隔離級別。事務隔離級別定義了在乙個事務中,哪些資料是對當前執行的語句 可見 的。在併發訪問資料庫時,事務隔離級別定義了多個事務之間對於同個目標資料來源訪問時的可交叉程度。可交叉程度可分為以下幾類。可交叉程度 dirty reads 髒讀 當乙個事務能看見另外乙個事務未提交的...
事務的隔離級別舉例 JDBC事務隔離級別
一組要麼同時執行成功,要麼同時執行失敗的sql語句。是資料庫操作的乙個執行單元。斷開與資料庫的連線 表示乙個事務內的所有操作是乙個整體,要麼全部成功,要麼全部失敗 表示乙個事務內有乙個操作失敗時,所有的更改過的資料都必須回滾到修改前狀態 事務檢視資料時資料所處的狀態,要麼是另一併發事務修改它之前的狀...