日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sqlserver中select造成死锁

發(fā)布時間:2024/4/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sqlserver中select造成死锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

項目上線,準(zhǔn)備驗收前出現(xiàn)了一個嚴(yán)重的問題:很多select語句作為死鎖的犧牲,大部分報表無法打開。這個問題影響范圍很大所有的報表都無法訪問,而我們的報表是放在電視上面輪播的,電視放在工廠里面,所以出現(xiàn)問題后,整個工廠都知道了。

  解決這個問題比較曲折,首先是寫SAP接口的同事發(fā)現(xiàn)了問題:SAP一直在傳錯誤數(shù)據(jù)導(dǎo)致產(chǎn)量表被鎖住。修改SAP傳輸?shù)腻e誤數(shù)據(jù)后,這個死鎖的問題沒有出現(xiàn)了。但是我查看生產(chǎn)環(huán)境服務(wù)器日志的時候,發(fā)現(xiàn)這個問題依然存在,由于客戶沒有提這個問題,我也就是沒有理由要求花時間修改了,因為我還有其他項目在忙。

  問題始終存在,它的暴露只是時間問題。過了一周,在我們要談項目驗收的時候,這個問題又暴露出來了。因為影響非常大,給客戶造成不好的印象。所以修改這個問題得到了老板的支持,說實話,我也頭一次遇到這樣的問題,也想不通select語句怎么就死鎖了。我知道這個問題很頭疼,好在得到老板的支持,會給足夠的時候我來解決問題,我也就有信心了。

  在網(wǎng)上找了很多文章,我的解決思路是:通過查詢語句查找死鎖相關(guān)的sql語句,只發(fā)現(xiàn)了被犧牲的那條sql語句,另外一條sql語句沒有找到,這條路走不通。接著就是重現(xiàn)問題,然后解決問題。這條路剛開始也走不通,也行不通,重現(xiàn)了一個下午有沒有發(fā)現(xiàn)問題。在快下班的時候,我迷茫了。第二天又網(wǎng)上找了半天資料,這個時候想到用sql server profiler去監(jiān)聽數(shù)據(jù)庫,悲劇的是客戶那邊放假了,連不到出問題的生產(chǎn)環(huán)境數(shù)據(jù)庫。接著跟同事聊這個問題,他給的建議依然是重現(xiàn),然后記得有個方法可以重現(xiàn),這個時候我才猛然想起來了有這檔子事。

  重現(xiàn)方法是有sql語句循環(huán)往產(chǎn)量表插入數(shù)據(jù),由于報表大多讀取產(chǎn)量表,然后報表就經(jīng)常死鎖。這個時候我看到希望了,只是不理解select語句怎么會引起死鎖,后來在網(wǎng)上認(rèn)真讀了一篇文章:SqlServer中select語句引起的死鎖(http://www.csharpwin.com/csharpspace/11505r288.shtml),讀懂這篇文章后我覺得跟我遇到的情況非常相似。

  通過他的理論我分析了下死鎖過程:

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

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

找到最快設(shè)置行版本級別的方法: 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

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

?

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

轉(zhuǎn)載于:https://www.cnblogs.com/lj821022/p/7355243.html

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的sqlserver中select造成死锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。