關係型資料庫的四種事務隔離級別

破棉襖發表於2015-02-26




SET TRANSACTION ISOLATION LEVEL

一、未提交讀READ UNCOMMITTED(髒讀)
意義:包含未提交資料的讀。例如,在多使用者環境下,使用者B更改了某行。使用者A在使用者B提交更改之前讀取已更改的行。如果此時使用者B再回滾更改,則使用者A便讀取了邏輯上從未存在過的行。


演示:
1)使用者B:
BEGIN TRAN
UPDATE test SET age=25 WHERE name = ‘AA’
2)使用者A:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED(此句不寫即預設為READ COMMITTED模式)
SELECT * FROM test(此時將查到AA的age值為25)
3)使用者B:
ROLLBACK(此時撤消了步驟1的UPDATE操作,則使用者A讀到的錯誤資料被稱為髒讀)

二、提交讀(READ COMMITTED)
意義:指定在讀取資料時控制共享鎖以避免髒讀。此隔離等級的主要作用是避免髒讀。
演示:
1)使用者B:
BEGIN TRAN
UPDATE test SET age=25 WHERE name = ‘AA’
2)使用者A:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM test (上句設定了提交讀模式,則此時將會查不到資料,顯示查詢等待中,直到使用者B進行了ROLLBACK或者COMMIT操作後,此語句才會生效)

三、不一致的分析REPEATABLE READ(重複讀)
意義:在多使用者環境下,使用者A開了一個事務,並且先對test表的某條記錄做了查詢(select * from test where name = ‘AA’),接著使用者B對test表做了更新並提交(update test set age=25 where name=’AA’),這時A再去查test表中的這條記錄,第一次讀到的age值為12,第二次為25,兩次讀到的資料不一樣,稱之為重複讀。

解決辦法:
在使用者A的事務執行之前,先設定SQL的隔離等級為REPEATABLE READ
SQL語句為SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
這樣在上圖第一步中,使用者A查詢完之後,使用者B將無法更新使用者A所查詢到的資料集中的任何資料(但是可以更新、插入和刪除使用者A查詢到的資料集之外的資料),直到使用者A事務結束才可以進行更新,這樣就有效的防止了使用者在同一個事務中讀取到不一致的資料。

四、幻象(SERIALIZABLE)
意義:在多使用者環境下,使用者A開啟了一個事務,並查詢test表中的所有記錄,然後使用者B在自己的事務中插入(或刪除)了test表中的一條記錄並提交事務,此時使用者A再去執行前面的查詢整張表記錄的操作,結果會多出(少了)一條記錄,此操作稱之為幻象。


解決辦法:
在使用者A的事務執行之前,先設定SQL的隔離等級為SERIALIZABLE
語句為SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
這樣在使用者A的事務執行過程中,別的使用者都將無法對任何資料進行更新、插入和刪除的操作,直到使用者A的事務回滾或者提交為止。這是四個隔離級別中限制最大的級別。因為併發級別較低,所以應只在必要時才使用該選項。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29754888/viewspace-1441535/,如需轉載,請註明出處,否則將追究法律責任。

相關文章