sqlserver中select造成死鎖


死鎖過程:

  • select語句使用非聚族索引查詢產量信息,會對非聚族索引添加共享鎖,由於非聚族索引上沒有select的全部數據列,(所以會有書簽查找出現,)需要查詢產量表。查詢產量表時,需要對產量表數據添加共享鎖,需要等待Update語句更新完產量表后釋放排他鎖。即Select等待Update釋放鎖。
  • 此時產量表上的Update/Insert語句更新產量信息的時候,會在聚族索引上做定位,添加排他鎖和修改非聚族索引的信息,問題就出在修改非聚族索引信息的時候,需要對非聚族做索引添加排他鎖。此時select語句已經在聚族索引上面添加了共享鎖,需要釋放后才能被添加排他鎖。即update語句需要等待select語句是否鎖。
  • 這樣死鎖就形成了。
 
於是只要讓查詢語句加共享鎖就解決問題了,sql server行版本級別控制能解決我的問題。

使用基於行版本控制的隔離級別:當在基於行版本控制的隔離下運行的事務讀取數據時,讀取操作不會獲取正被讀取的數據上的共享鎖(S 鎖)

找到最快設置行版本級別的方法:
 
 
if(charindex('Microsoft SQL Server 2008',@@version) > 0) 
begin 

declare @sql varchar(8000) 
select @sql = ' 
ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ; 
ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON; 
ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;' 

Exec(@sql) 
end 
 

很神奇,這樣設置后,死鎖的問題就不存在了。

 

查詢是否設置成功:
select is_read_committed_snapshot_on from sys.databases where name = DB_Name() 


免責聲明!

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



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