數(shù)據(jù)庫(kù)中活鎖和死鎖的概念 數(shù)據(jù)庫(kù)中死鎖是什么產(chǎn)生的?
數(shù)據(jù)庫(kù)中死鎖是什么產(chǎn)生的?數(shù)據(jù)庫(kù)操作的死鎖是不可避免的,本文并不打算討論死鎖如何產(chǎn)生,重點(diǎn)在于解決死鎖,通過(guò)SQL Server 2005, 現(xiàn)在似乎有了一種新的解決辦法。 將下面的SQL語(yǔ)句放在兩個(gè)
數(shù)據(jù)庫(kù)中死鎖是什么產(chǎn)生的?
數(shù)據(jù)庫(kù)操作的死鎖是不可避免的,本文并不打算討論死鎖如何產(chǎn)生,重點(diǎn)在于解決死鎖,通過(guò)SQL Server 2005, 現(xiàn)在似乎有了一種新的解決辦法。 將下面的SQL語(yǔ)句放在兩個(gè)不同的連接里面,并且在5秒內(nèi)同時(shí)執(zhí)行,將會(huì)發(fā)生死鎖。 use Northwindbegin tran insert into Orders(CustomerId) values(@#ALFKI@#) waitfor delay @#00:00:05@# select * from Orders where CustomerId = @#ALFKI@#commitprint @#end tran@# SQL Server對(duì)付死鎖的辦法是犧牲掉其中的一個(gè),拋出異常,并且回滾事務(wù)。在SQL Server 2000,語(yǔ)句一旦發(fā)生異常,T-SQL將不會(huì)繼續(xù)運(yùn)行,上面被犧牲的連接中, print @#end tran@#語(yǔ)句將不會(huì)被運(yùn)行,所以我們很難在SQL Server 2000的T-SQL中對(duì)死鎖進(jìn)行進(jìn)一步的處理。 現(xiàn)在不同了,SQL Server 2005可以在T-SQL中對(duì)異常進(jìn)行捕獲,這樣就給我們提供了一條處理死鎖的途徑: 下面利用的try ... catch來(lái)解決死鎖。 SET XACT_ABORT ONdeclare @r intset @r = 1while @r 0begin declare @ErrorMessage nvarchar(4000) declare @ErrorSeverity int declare @ErrorState int select @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE() raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState )end
數(shù)據(jù)庫(kù)死鎖原因是什么呢?
一般情況只發(fā)生鎖超時(shí),就是一個(gè)進(jìn)程需要訪問(wèn)數(shù)據(jù)庫(kù)表或者字段的時(shí)候,另外一個(gè)程序正在執(zhí)行帶鎖的訪問(wèn)(比如修改數(shù)據(jù)),那么這個(gè)進(jìn)程就會(huì)等待,當(dāng)?shù)攘撕芫面i還沒有解除的話就會(huì)鎖超時(shí),報(bào)告一個(gè)系統(tǒng)錯(cuò)誤,拒絕執(zhí)行相應(yīng)的SQL操作。發(fā)生死鎖的情況比較少,比如一個(gè)進(jìn)程需要訪問(wèn)兩個(gè)資源(數(shù)據(jù)庫(kù)表或者字段),當(dāng)獲取一個(gè)資源的時(shí)候進(jìn)程就對(duì)它執(zhí)行鎖定,然后等待下一個(gè)資源空閑,這時(shí)候如果另外一個(gè)進(jìn)程也需要兩個(gè)資源,而已經(jīng)獲得并鎖定了第二個(gè)資源,那么就會(huì)死鎖,因?yàn)楫?dāng)前進(jìn)程鎖定第一個(gè)資源等待第二個(gè)資源,而另外一個(gè)進(jìn)程鎖定了第二個(gè)資源等待第一個(gè)資源,兩個(gè)進(jìn)程都永遠(yuǎn)得不到滿足。
為什么服務(wù)器的宕機(jī)一般都發(fā)生在凌晨使用率最低的時(shí)候?
來(lái)自16年經(jīng)驗(yàn)老程序員的靠譜回答。
主要有以下幾個(gè)原因
1.凌晨時(shí)服務(wù)器很忙
首先,確實(shí)服務(wù)器的宕機(jī)一般都發(fā)生在凌晨使用率最低的時(shí)候,但是這個(gè)使用率只是針對(duì)用戶而言的。
實(shí)際上,在凌晨的時(shí)候,服務(wù)器是很忙的。主要忙哪些事情呢?主要是一些定時(shí)任務(wù),還有數(shù)據(jù)庫(kù)備份等。很多比較耗時(shí)的操作比如報(bào)表統(tǒng)計(jì)都會(huì)安排在半夜,以免半天影響正常業(yè)務(wù),所以這個(gè)時(shí)候,服務(wù)器都是在高負(fù)荷運(yùn)轉(zhuǎn)的,容易產(chǎn)生事故。
2.一般晚上的時(shí)候會(huì)上線新功能
同理,發(fā)布新代碼或者更改功能,也會(huì)選擇在晚上的業(yè)務(wù)低峰期。無(wú)論前期的測(cè)試工作做的多么到位,也難免會(huì)隱藏一些bug,到了凌晨,這些bug(比如死循環(huán))已經(jīng)跑了一段時(shí)間了,在無(wú)人值守的情況下就可能觸發(fā)各種故障。
如果上線時(shí)間比較短還好,遇到更新比較大的情況下,程序員奮戰(zhàn)到大半夜,這個(gè)情況下人是很疲憊的,更容易忙中出錯(cuò)。
3.無(wú)人值守導(dǎo)致修復(fù)變慢
比如死循環(huán)和內(nèi)存泄漏,是需要經(jīng)過(guò)一段時(shí)間才能表現(xiàn)出來(lái)的。白天有人實(shí)時(shí)監(jiān)控,自然出現(xiàn)故障的幾率比較小,就算出現(xiàn)故障了,也能很快修復(fù),讓用戶無(wú)法覺察。
4.凌晨是黑客作案高峰期
夜黑風(fēng)高,殺人越貨。這個(gè)時(shí)間點(diǎn)是正常人休息時(shí)間,而黑客則選擇在這個(gè)時(shí)候活動(dòng),不論是安全攻擊,或者是DDOS,都可能造成服務(wù)器故障。