在數據庫操作中,爲了有效保證併發讀取數據的正確性,我們提出了事務的隔離級別:
大多數數據庫系統的默認事務隔離級別爲:讀已提交。
經常使用到的數據庫系統的默認事務隔離級別如下:
SQL server:讀已提交
PostgreSQL:讀已提交
MySQL:可重複讀
Oracle:可重複讀(Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。所以Oracle不支持髒讀。)
讀未提交(又叫髒讀,即讀取未提交的事務,肯定會出現問題):是指讀數據時數據庫不要求有共享鎖(讀鎖)。因此,其他事務可以讀取隨後可能會回滾的未提交的事務,即髒讀。未提交的事務都能被其他事務讀取到,你說這數據髒不髒?
讀已提交(讀取已提交的事務,仍然會出現問題):是指數據庫中需要有共享鎖(讀鎖)才能讀取數據。只能讀取已經提交的數據,但在事務結束之前可以修改這些數據,會造成不可重複讀的問題。一個事務重新讀取前面讀取過的數據,發現該數據已經被另一個已提交事務修改。
可重複讀(可以重複讀取同一條數據,還是有可能出現問題):是指一個事務中用到的所有數據都有鎖,其他事務不能更新這些數據。但是其他事務可以向數據集中插入新項,如果事務再次從這個數據集中讀取數據,那麼就會出現“虛讀”,又可以稱爲幻讀。我們可以簡單理解幻讀:在一個事務的兩次查詢中,數據的筆數不一致。
可串行化(可序列化,不會出現任何問題):是指一個事務中用到的所有數據都有鎖,並且其他的事務不能更新這個數據集或向這個數據集中插入數據項。
顯而易見,如果一個數據庫只支持頁級鎖(不支持行級鎖),那麼可重複讀和可序列化是相同的。這是因爲其他事務在前一個事務完成之前不能插入單個數據行,因爲整頁數據都被鎖住了。
補充:
共享鎖(S鎖):若事務T對數據對象A加上S鎖,則事務T只能讀A, 不能修改A;其他事務只能再對A加S鎖(其他事務只能讀取A),而不能加X鎖(不能修改A),直到T釋放A上的S鎖。這就保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
排他鎖(X鎖):若事務T對數據對象A加上X鎖,則只允許T讀取和修改A,其他任何事務都不能再對A加任何類型的鎖(其他事務即不能讀也不能修改),直到T釋放A上的X鎖。這就保證了其他事務在T釋放A上的X鎖之前不能再讀取和修改A。