資料庫事務隔離級別
鎖我們需要捨棄一部分的隔離性
來換取資料庫的併發的效能,怎麼個捨棄法呢?先得看一下訪問相同資料的事務在不保證序列執行(也就是執行完乙個再執行另乙個)的情況下可能會出現哪些問題:
乙個事務讀取另外乙個事務未提交的更新事務。
事務1事務2
select age from table1 where id = 1 – 結果是 20
update table1 set age = 30 where id = 1 – 這裡沒有提交
select age from table1 where id = 1 – 結果是 30
事務2回滾
備註正常事務1 的結果應該是20
這裡的事務1就讀取了一條髒資料。 – 髒讀
在乙個事務範圍內, 同樣的兩次查詢得到不同的結果。這裡是由於系統中其他的事務提交引起的。
事務1事務2
select age from table1 where id = 1 – 結果是 20
update table1 set age = 30 where id = 1 – 這裡提交了
select age from table1 where id = 1 – 結果是 30
備註按照正確邏輯,事務a前後兩次讀取到的資料應該一致
幻讀是不可重複讀的一種特殊情況, 在同乙個事務範圍內, 查詢兩次結果得到條數不一樣。
事務1事務2
select count(*) from table1 結果是 20
insert into table1 value(9,…) – 這裡提交了
select count(*) from table1 – 結果是 21
備註按照正確邏輯,事務a前後兩次讀取到的資料總量應該一致
什麼是資料庫隔離級別
我們上邊所說的捨棄一部分隔離性來換取一部分效能在這裡就體現在:設立一些隔離級別,隔離級別越低,越嚴重的問題就越可能發生。有一幫人(並不是設計mysql
的大叔們)制定了乙個所謂的sql標準
,在標準中設立了4個隔離級別
:
乙個事務可以讀取另外乙個事務未提交的事務。
1.事務在讀資料時候沒有加鎖。
2.在修改資料的時候只是對事務增加行級共享鎖。產生現象:
事務1在讀取的時候, 事務2也可以進行讀取以及修改。(事務在讀取的時候是不加鎖的)
事務2在這條記錄進行修改時候, 事務1可以進行讀取。(因為事務在修改的時候只是加了共享鎖),
所以,這樣就會產生髒讀。
當隔離級別設定為read uncommitted 時,就可能出現髒讀,如何避免髒讀,請看下乙個隔離級別。
讀已提交是postgresql裡的預設隔離級別。
當乙個事務執行在這個隔離級別時, select查詢(沒有for update/share子句)只能看到其它事務已提交的資料。
實際上,select 查詢看到乙個在查詢開始執行的瞬間該資料庫的乙個快照。 不過,select看得見其自身所在事務中之前的更新的執行結果,即使它們尚未提交。
請注意, 在同乙個事務裡兩個相鄰的select命令可能看到不同的快照,因為其它事務會坑你在兩個select執行期間提交。
不會出現可髒讀,但是不可重複讀
即使資料被其他事物修改, 當前事務也不會讀取到新的資料
重複讀事務中的查詢看到的是事務開始時的快照, 而不是該事務內部當前查詢開始時的快照,這樣, 同乙個事務內部後面的select命令總是看到同樣的資料,
也就是說,它們看不到 它們自身事務開始之後提交的其他事務所做出的改變。
不會出現可髒讀, 可重複讀, 可以幻讀
可序列化級別提供最嚴格的事務隔離。這個級別為所有已提交事務模擬序列的事務執行, 就好像事務將被乙個接著乙個那樣序列(而不是並行)的執行。
不過,正如可重複讀隔離級別一樣, 使用這個級別的應用必須準備在序列化失敗的時候重新啟動事務。
事實上,該隔離級別和可重複讀希望的完全一樣, 它只是監視這些條件,以所有事務的可能的序列不一致的(一次乙個)的方式執行並行的可序列化事務執行的行為。
這種監測不引入任何阻止可重複讀出現的行為,但有一些開銷的監測,檢測條件這可能會導致序列化異常 將觸發序列化失敗。
鎖就是防止其他事務訪問指定的資源的手段。鎖是實現併發控制的主要方法,是多個使用者能夠同時操縱同乙個資料庫中的資料而不發生資料不一致現象的重要保障。 一般來說,鎖可以防止髒讀、不可重複讀和幻覺讀。
快速理解髒讀 不可重複讀 幻讀
a事務讀取b事務尚未提交的資料,此時如果b事務發生錯誤並執行回滾操作,那麼a事務讀取到的資料就是髒資料。就好像原本的資料比較乾淨 純粹,此時由於b事務更改了它,這個資料變得不再純粹。這個時候a事務立即讀取了這個髒資料,但事務b良心發現,又用回滾把資料恢復成原來乾淨 純粹的樣子,而事務a卻什麼都不知道...
快速理解髒讀 不可重複讀 幻讀
髒讀 讀取未提交資料 a事務讀取b事務尚未提交的資料,此時如果b事務發生錯誤並執行回滾操作,那麼a事務讀取到的資料就是髒資料。就好像原本的資料比較乾淨 純粹,此時由於b事務更改了它,這個資料變得不再純粹。這個時候a事務立即讀取了這個髒資料,但事務b良心發現,又用回滾把資料恢復成原來乾淨 純粹的樣子,...
髒讀,不可重複讀,幻讀
髒讀,不可重複讀,幻讀是由於資料庫事務的隔離性導致的問題。髒讀 乙個事務讀取到了其它未提交事務操作的記錄。不可重複讀 乙個事務a內,首次查詢到一條相同記錄,然後事務b修改該條記錄並提交,事務a再次執行相同查詢,得到了事務b更新後的結果,事務a兩次相同的查詢,卻得到了不同的結果,這個叫做不可重複讀。是...