国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

第17/24周 悲觀并發控制(Pessimistic Concurrency)

2024-07-21 02:46:19
字體:
來源:轉載
供稿:網友
第17/24周 悲觀并發控制(Pessimistic Concurrency)

大家好,歡迎回到性能調優培訓。今天標志著第5個月培訓的開始,這個月我們會談論SQL Server里的鎖、阻塞和死鎖(Locking, Blocking, and Deadlocking)。

SQL Server提供悲觀和樂觀并發控制模式,它們用來定義并發查詢的執行。這期我會給你講解悲觀并發控制模式里各種隔離級別概況,下周我會進一步介紹自SQL Server 2005起引入的樂觀隔離級別情況。

悲觀隔離級別(Pessimistic Isolation Levels)

悲觀隔離級別意味著讀查詢(SELECT)阻塞寫查詢(INSERT,UPDATE,DELETE),而且寫查詢阻塞讀查詢。SQL Server對此行為使用所謂的鎖(Locks)

  • 讀操作獲取共享鎖(Shared Locks (S))
  • 寫操作獲取排它鎖(Exclusive Locks (X))

2個鎖之間互不兼容。這就是說不能同時讀寫一條記錄。如果這個發生的話,就會出現所謂的阻塞(Blocking)情形。當你設置指定的事務隔離級別(transaction isolation level)后,你就直接影響讀查詢在寫查詢同時進行時如何把持它們的共享鎖(S)。你不能影響寫操作——當你在表上修改一條記錄(INSERT,UPDATE,DELETE)總會拿到排它鎖(X)。

默認情況每個查詢在提交讀(Read committed)隔離級別運行。提交讀意味著SQL Server在記錄讀取時會在記錄上獲取一個共享鎖(S),一旦記錄完全讀取或處理,共享鎖(S)就是立即釋放。當你對表進行掃描(Scan)運算符(單線程),在給定時間內只有一個共享鎖(S)把持著。因為這個行為,其他事務隨后修改記錄是可能的。如果你在同個事務里讀取同個記錄,你應該使用所謂的不可重復讀(Non-Repeatable Read):你多次讀取一條記錄,但卻返回不同的值。

如果你不能忍受可重復讀的行為,你可以使用限制更多的可重復讀(Repeatable Read)。這個隔離級別給你可重復的讀(因名而來),即當你讀取一條記錄時,SQL Server會保持共享鎖(S)直到你事務的結束。因此在你讀取的事務期間,沒有人可以獲取排它鎖(X)來改變你的記錄(因為這個不兼容性,排它鎖會向阻塞讓步)。這個方法有優點也有缺點:一方面你獲得更準確的記錄(可重復讀),另一方面你會有更多的阻塞發生,因為讀操作把持它們的共享鎖(S)直到它們事務的結束。你要在并發控制和數據準確性之間權衡。

你還可以通過改變隔離級別為可串行化(Serializable)來進一步限制。使用那個在SQL Server里最有限制的隔離級別——你可以避免所謂的虛影記錄(Phantom Records)。當你多次從表獲取記錄時,虛影記錄會出現并消失。為了避免虛影記錄,SQL Server使用所謂的Key Range Locking技術,即通過鎖定你初次獲取的范圍數據。

因此沒有其它的并發查詢可以在鎖定范圍內插入記錄。從范圍內刪除記錄,或“移動”另一條記錄到此范圍的更新語句都是不可能的。這樣的查詢只會阻塞。在你行范圍定義記錄的查詢謂語上,你也需要支持的索引。用支持的索引,SQL Server會鎖定各個索引鍵。沒有支持的索引,SQL Server就會鎖定你的整張表,這會大大傷及你數據庫的并發和工作量!

最后SQL Server支持未提交讀(Read Uncommitted)隔離級別。使用提交讀,當讀取數據時,不需要獲得共享鎖(S)。因此從當前正在進行的事務中讀到未提交的數據是可能的。那就是所謂的臟讀(Dirty Read)。如果這樣的事務回滾,你就讀到了數據庫里邏輯上不存在的數據。這是個并不推薦的隔離級別,用的時候要慎重考慮下。使用著名的NOLOCK查詢提示就可以強制臟讀。

悲觀隔離級別并不復雜,是不是?隔離級別就是表示對于讀取的數據共享鎖(S)可以把持多久。基于此,隔離級別就定義了在數據讀取期間,哪些是可以操作的,哪些是不能操作的。看下圖就會明白。

                臟讀(Dirty Read)  不可重復讀(Non-Repeatable Read)  虛影記錄(Phantom Records)

未提交讀(Read Uncommitted)   是          是                  是

提交讀(Read Committed)     否          是                  是

重復讀(Repeatable Read)     否          否                  是

可序列話(Serializable)       否          否                  否

另外為了保證查詢的正確性,對于指定的隔離級別,SQL Server會臨時提升隔離級別。你可以圍觀這個文章:事務隔離級別神話與誤解。

小結

今天你已經學習了SQL Server里各個悲觀隔離級別的基礎。當你對SQL Server里的鎖和阻塞情況進行故障排除時,這是你必須知道的基礎:讀查詢(SELECT)阻塞寫查詢(INSERT,UPDATE,DELETE),而且寫查詢阻塞讀查詢。

下周我們會談論SQL Server支持的使用樂觀并發控制(Optimistic Concurrency)組合的另外2個隔離級別。請繼續關注!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 小金县| 枣阳市| 沿河| 化州市| 丰都县| 昌平区| 双流县| 博白县| 疏勒县| 淮滨县| 东兰县| 清远市| 习水县| 清远市| 高邑县| 岑溪市| 舒城县| 徐州市| 瓮安县| 涿鹿县| 瑞昌市| 英吉沙县| 安化县| 白玉县| 揭阳市| 东兰县| 乐陵市| 肥城市| 广宗县| 莆田市| 普兰店市| 泰兴市| 棋牌| 县级市| 滕州市| 阿勒泰市| 崇义县| 苍溪县| 岚皋县| 东丽区| 故城县|