第18/24周 樂觀並發控制(Optimistic Concurrency)


大家好,歡迎回到性能調優培訓上個星期我通過討論悲觀並發模式拉開了第5個月培訓的序幕。今天我們繼續,討論下樂觀並發模式(Optimistic Concurrency)

行版本(Row Versioning)

樂觀並發模式自SQL Server 2005后引入,並基於行版本控制(Row Versioning)原則。行版本控制背后的想法是讀操作(SELECT查詢)不再需要獲得共享鎖(Shared Lock)。不去等待直到成功獲得共享鎖(Shared Lock),讀操作是返回行前一個提交的版本。老的,前一個版本被存儲在所謂的版本存儲(Version Store)里,這個在TempDb里永駐。寫操作(UPDATE,DELETE語句)明確復制老版本到版本存儲,新版本中含一個指針指向versionstore里面舊行。下圖詮釋了這個概念。

 

增加這個指針的一個副作用是每個記錄會增加額外的14 bytes。這會帶來:

  • 堆表上的轉發記錄(Forwarding Records)
  • 聚集表上的頁分裂(Page Splits)

另外,你也要按需計划和大小TempDb,因為你會引入額外的I/O,在默認配置下會帶來競爭問題。現在讓我們看看SQL Server提供給你的2個新的樂觀隔離級別(optimistic isolation levels)。

樂觀隔離級別(Optimistic Isolation Levels)

自SQL Server 2005起,關系引擎提供2個新的樂觀隔離級別,它們是基於上一部分討論過的行版本控制概念。

  • 讀提交快照隔離(Read Committed Snapshot Isolation (RCSI))
  • 快照隔離(Snapshot Isolation (SI))

我們來詳細看下這2個隔離級別。RCSI提供你基於快照語句級別的隔離。換句話說,SQL Server總會返回你在語句開始前有效的版本。它是提交讀隔離級別(Read Committed Isolation Level)的樂觀實現。因此使用這個隔離級別你會有不可重復讀(Non-Repeatable Reads)。 

1 ALTER DATABASE AdventureWorks2012 SET READ_COMMITTED_SNAPSHOT ON
2 GO
3 
4 -- Check if RCSI is now enabled
5 SELECT  name,is_read_committed_snapshot_on
6 FROM sys.databases
7 WHERE database_id = DB_ID('AdventureWorks2012')
8 GO

RCSI的一個好處是對數據庫/應用程序本身它是完全透明的:你重要在數據庫上啟用它,然后對於每個查詢新的默認隔離級別是讀提交快照隔離(Read Committed Snapshot Isolation)。因此通過對指定數據庫啟用RCSI,你可以克服鎖和阻塞問題,即使死鎖問題也很容易。下面代碼顯示了對於給出的數據庫如何啟用RCSI:

對於你SELECT查詢,如果你想有重復讀(Repeatable Reads)的樂觀方式,你可以使用快照隔離(Snapshot Isolation (SI))隔離級別。快照隔離提供你開箱即用(out of box)的重復讀,這就是說你總拿到在你事務開始前有效的行版本。遺憾的是快照隔離並不完全透明:

  • 快照隔離級別必須通過會話明確請求。因此在你的程序里你需要修改代碼。
  • 你的查詢會執行如所謂的更新沖突(Update Conflicts),SQL Server會回滾事務。因此在你的程序里你需要相應的進行處理這個情況。

下面代碼向你展示了對於指定的數據庫,如何啟用快照隔離(Snapshot Isolation),如何請求這個新的隔離級別。

 1 -- Enable Snapshot Isolation (SI)
 2 ALTER DATABASE AdventureWorks2012 SET ALLOW_SNAPSHOT_ISOLATION ON
 3 GO
 4 
 5 -- Check if SI is now enabled
 6 SELECT name, snapshot_isolation_state,  snapshot_isolation_state_desc
 7 FROM sys.databases
 8 WHERE database_id = DB_ID('AdventureWorks2012')
 9 GO
10 
11 USE AdventureWorks2012
12 GO
13 
14 -- Setting the Isolation Level to Snapshot Isolation
15 SET TRANSACTION ISOLATION LEVEL SNAPSHOT
16 GO

小結

今天你學習了自SQL Server 2005起支持的2個樂觀隔離級別。提交讀快照隔離(Read Committed Snapshot Isolation (RCSI))提供你基於語句級別的隔離,快照隔離(Snapshot Isolation (SI))提供你基於事務級別的隔離,因為2個隔離級別使在永駐在TempDb里的版本存儲,對於TempDb你需要仔細計划和指定標准。

下周我會談下SQL Server 里鎖和阻塞發生的問題:鎖升級(Lock Escalations)。請繼續關注!

圍觀PPT:

0928_18_樂觀並發控制.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM