SQL Server 2005遊標的行為變化導致的死鎖問題
產生死鎖的場景:
連線1:
DECLARE @cursor INT
EXEC sp_cursoropen @cursor OUTPUT, 'select * from employee', 2, 2
EXEC sp_cursorfetch @cursor, 2, 0,1
select @cursor
--返回180150003
連線2:
DECLARE @cursor INT
EXEC sp_cursoropen @cursor OUTPUT, 'select * from employee', 2, 2
EXEC sp_cursorfetch @cursor, 2, 0,1
select @cursor
現在連線2被連線1阻塞
接下來執行:
連線1:
EXEC sp_cursor 180150003, 33, 1, '', @ContactID=5 –這個語句實際上是做update
出現錯誤1205。
連線2仍舊被連線1阻塞:
連線1正持有鍵上的U鎖,連線2在等待同一個鍵值上的U鎖。
我們來具體看一下游標的幾個呼叫方式在資料庫上申請和釋放lock的過程
--建立一個dynamic遊標
DECLARE @cursor INT
EXEC sp_cursoropen @cursor OUTPUT, 'select * from employee', 2, 2
--提取下一行;這將行放到fetch buffer中
EXEC sp_cursorfetch @cursor, 2, 0,1
--更新fetch buffer中的行
EXEC sp_cursor @cursor, 33, 1, '', @zip=5
--關閉遊標
EXEC sp_cursorclose @cursor
這裡我們介紹trace flag 1200來輸出語句在資料庫上對鎖申請和釋放的日誌:
DBCC traceon(1200,-1)
關閉trace flag: dbcc traceoff(1200,-1)
對於上面的語句,在2005版本中:
EXEC sp_cursorfetch @cursor, 2, 0,1
Process 53 acquiring S lock on RID: 6:1:60795:0 (class bit0 ref1) result: OK
Process 53 acquiring U lock on RID: 6:1:60795:0 (class bit10000000 ref0) result: OK
EXEC sp_cursor @cursor, 33, 1, '', @zip=5
Process 53 acquiring U lock on RID: 6:1:60795:0 (class bit0 ref1) result: OK
Process 53 acquiring X lock on RID: 6:1:60795:0 (class bit2000000 ref0) result: OK
Process 53 releasing lock reference on RID: 6:1:60795:0
在2000版本:
EXEC sp_cursoropen @cursor OUTPUT, 'select * from employee', 2, 2
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit2000000 ref1) result: OK
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit10000000 ref0) result: OK
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit0 ref1) result: OK
EXEC sp_cursor @cursor, 33, 1, '', @zip=5
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit0 ref1) result: OK
Process 51 acquiring X lock on RID: 5:1:240:0 (class bit2000000 ref1) result: OK
Process 51 releasing lock reference on RID: 5:1:240:0
接下來,我們對上面現象進行一定的說明:
在2005上,從cursor開啟,到執行update,整個lock的變化過程為:
S(共享鎖)à U(更新鎖)-->X(排他鎖)
Process 53 acquiring S lock on RID: 6:1:60795:0 (class bit0 ref1) result: OK
Process 53 acquiring U lock on RID: 6:1:60795:0 (class bit0 ref1) result: OK
Process 53 acquiring X lock on RID: 6:1:60795:0 (class bit2000000 ref0) result: OK
而在2000上,從cursor開啟,到執行update,整個lock的變化過程為:
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit10000000 ref0) result: OK
Process 51 acquiring U lock on RID: 5:1:240:0 (class bit0 ref1) result: OK
Process 51 acquiring X lock on RID: 5:1:240:0 (class bit2000000 ref1) result: OK
1.在該錯誤重現中,滾動鎖定(scroll lock)在GetRow上提取S鎖,而後是U鎖,就導致了死鎖和錯誤結果的出現。
2.提取並沒有滾動鎖定基本的索引
正如上面那個簡單的錯誤重現,我們可以發現,2005中 fetch過程中S鎖到U鎖的升級導致了deadlock的出現。對於S鎖,兩個連線可以在同一時間申請同一行資料上的S鎖,而當兩個連線都有對S鎖進行升級到U鎖的時候,一定會出現deadlock。
在SQL Server 2000版本中,fetch鎖定直接請求U鎖,這種情況下,就只有一個連線可以在同一時間對同一資料行上申請U鎖了。這樣直接申請U的行為,雖然避免了deadlock,但是會導致更多的lock和更長的lock持有時間,從而導致更多的阻塞出現。
這實際上是SQL Server 2005的一個設計變化,SQL Server2008也是如此。除了使用相應的引數保證兩個連線不要訪問同樣的資料,沒有解決該問題的方案。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25175503/viewspace-704919/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 的死鎖SQLServer
- Oracle死鎖一例(ORA-00060),鎖表導致的業務死鎖問題Oracle
- AdornerDecorator的CacheMode繫結和windows鎖屏導致TableControl鎖死問題Windows
- 線上問題排查:記一次 Redis Cluster Pipeline 導致的死鎖問題Redis
- 因為修改windows管理員密碼導致sql server 2005不能啟動處理Windows密碼SQLServer
- 分散式鎖導致的超賣問題分散式
- Slave SQL執行緒與PXB FTWRL死鎖問題分析SQL執行緒
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- SQL Server技術問題之遊標優缺點SQLServer
- EfCore3的OwnedType會導致Sql效率問題SQL
- 硬碟問題導致Gbase資料庫叢集SQL任務執行效率變慢硬碟資料庫SQL
- Linux雜談:程式鎖核+實時執行緒導致的讀寫鎖死迴圈Linux執行緒
- MySQL死鎖問題MySql
- sql server 2005 資料修改的內部原理SQLServer
- SQL Server 資料庫查詢死鎖的處理步驟SQLServer資料庫
- 如何捕獲和記錄SQL Server中發生的死鎖SQLServer
- SQLServer 如何收集資料以排除 SQL 死鎖問題SQLServer
- sql server 2005資料庫快照SQLServer資料庫
- Oracle優化案例-join列索引缺失導致的sql效能問題(二十六)Oracle優化索引SQL
- 已安裝 SQL Server 2005 Express 工具。若要繼續,請刪除 SQL Server 2005 Express 工具SQLServerExpress
- MySQL 死鎖問題分析MySql
- Python | 多執行緒死鎖問題的巧妙解決方法Python執行緒
- MySQL死鎖系列-線上死鎖問題排查思路MySql
- SQL Server 2005效能調整一(zt)SQLServer
- SQL Server 2005效能調整二(zt)SQLServer
- 2024.10.2 座標變化 + 揹包問題剩下的題
- impdp導致主鍵索引的變化索引
- MySQL鎖等待與死鎖問題分析MySql
- ANALYZE導致的阻塞問題分析
- SQL Server 2005的複製儲存過程選項BYSQLServer儲存過程
- 淺談SQL Server中的快照問題SQLServer
- 解決頁面豎向捲軸導致元素尺寸發生變化的問題
- SpringBoot Seata 死鎖問題排查Spring Boot
- 有問題的mybatis的sql導致對資料庫進行了批量的修改MyBatisSQL資料庫
- 記一次鎖使用不當導致Dubbo執行緒阻塞問題執行緒
- 在 SQL Server 中查詢活動連線和死鎖SQLServer
- Oracle資料傾斜導致的問題-無繫結變數Oracle變數
- Oracle資料傾斜導致的問題-有繫結變數Oracle變數
- 記一次,因表變數導致SQL執行效率變慢變數SQL