解決資料庫並發讀取錯亂的途徑之一就是使用事務進行操作,並且設定相應的交易隔離等級,現在就解釋一下SQL Server的四種隔離等級。
SQL Server的四種隔離等級知識點整理,特別製作了流程圖,方便以後查看!
SET TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
一、未提交讀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的交易回復或者提交為止。這是四個隔離等級中限制最大的層級。因為並發層級較低,所以應只在必要時才使用該選項。