国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

SQL Server鎖定和阻塞 防范數(shù)據(jù)泥石流

數(shù)據(jù)庫 SQL Server
在這里我們將討論的是SQL Server鎖定和阻塞,并將討論產(chǎn)生這種情況的原因,希望對各位DBA有所幫助。

本帖提供兩種做法,可避免讓 client-side 程序,持續(xù)等待 SQL Server 中事務(wù)鎖定造成的不正常或長時(shí)間阻塞,而讓用戶也無限期等待,甚至造成 connection pooling 連接數(shù)超過容量。

日前公司 server-side 有組件,疑似因撰寫時(shí) exception-handling 做得不周全,導(dǎo)致罕見的特殊例外發(fā)生時(shí),讓 SQL Server 的事務(wù)未執(zhí)行到 cmmmit 或 rollback,造成某些表或記錄被「鎖定 (lock)」。后來又有大量的 request,要透過代碼訪問這些被鎖定的記錄,結(jié)果造成了嚴(yán)重的長時(shí)間「阻塞」,最后有大量 process 在 SQL Server 呈現(xiàn)「等待中」的狀態(tài)。

由于 SQL Server 的「事務(wù)隔離級別」默認(rèn)是 READ COMMITTED (事務(wù)期間別人無法讀取),加上 SQL Server 的鎖定造成阻塞時(shí),默認(rèn)是別的進(jìn)程必須無限期等待 (LOCK_TIMEOUT = -1)。結(jié)果這些大量的客戶端 request 無限期等待永遠(yuǎn)不會提交或回滾的事務(wù),并一直占用著 connection pool 中的資源,最后造成 connection pooling 連接數(shù)目超載。

查了一些書,若我們要查詢 SQL Server 目前會話中的 lock 超時(shí)時(shí)間,可用以下的命令:

  1. SELECT @@LOCK_TIMEOUT 

默認(rèn)為 -1,意即欲訪問的對象或記錄被鎖定時(shí),會無限期等待。若欲更改當(dāng)前會話的此值,可用下列命令:

  1. SET LOCK_TIMEOUT 3000 

后面的 3000,其單位為毫秒,亦即會先等待被鎖定的對象 3 秒鐘。若事務(wù)仍未釋放鎖,則會拋回如下代號為 1222 的錯(cuò)誤信息,可供程序員編程時(shí)做相關(guān)的逾時(shí)處理:

消息 1222,級別 16,狀態(tài) 51,第 3 行

已超過了鎖請求超時(shí)時(shí)段。

若將 LOCK_TIMEOUT 設(shè)置為 0,亦即當(dāng)欲訪問對象被鎖定時(shí),完全不等待就拋回代號 1222 的錯(cuò)誤信息。此外,此一 SET LOCK_TIMEOUT 命令,影響范例只限當(dāng)前會話,而非對某個(gè)表做永久的設(shè)置。

-------------------------------------------------------------------------------------------

接下來我們在 SSMS 中,開兩個(gè)會話 (查詢窗口) 做測試,會話 A 創(chuàng)建會造成阻塞的事務(wù)進(jìn)程,會話 B 去訪問被鎖定的記錄。

--會話 A

  1. BEGIN TRAN;  
  2. UPDATE Orders SET EmployeeID=7 WHERE OrderID=10248 

--rollback; --故意不提交或回滾

--會話 B

  1. SELECT * FROM Orders WHERE OrderID=10248 

分別執(zhí)行后,因?yàn)橛L問的記錄是同一條,按照 SQL Server 「事務(wù)隔離級別」和「鎖」的默認(rèn)值,會話 B 將無法讀取該條數(shù)據(jù),而且會永遠(yuǎn)一直等下去 (若在現(xiàn)實(shí)項(xiàng)目里寫出這種代碼,就準(zhǔn)備被客戶和老板臭罵)。

-------------------------------------------------------------------------------------------

若將會話 B 先加上 SET LOCK_TIMEOUT 3000 的設(shè)置,如下,則會話 B 會先等待 3 秒鐘,才拋出代號 1222 的「鎖請求已超時(shí)」錯(cuò)誤信息:

  1. SET LOCK_TIMEOUT 3000  
  2. UPDATE Orders SET EmployeeID=7 WHERE OrderID=10248  
  3. --SET LOCK_TIMEOUT -1 

執(zhí)行結(jié)果:

消息 1222,級別 16,狀態(tài) 51,第 3 行

已超過了鎖請求超時(shí)時(shí)段。

語句已終止。

-------------------------------------------------------------------------------------------

另根據(jù)我之前寫的文章「30 分鐘快快樂樂學(xué) SQL Performance Tuning」所述:
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html

撰寫不當(dāng)?shù)?SQL 語句,會讓數(shù)據(jù)庫的索引無法使用,造成全表掃描或全聚集索引掃描。例如不當(dāng)?shù)模篘OT、OR 算符使用,或是直接用 + 號做來串接兩個(gè)字段當(dāng)作 WHERE 條件,都可能造成索引失效,變成全表掃描,除了性能變差之外,此時(shí)若這句不良的 SQL 語句,是本帖前述會話 B 的語句,由于會造成全表掃描,因此就一定會被會話 A 的事務(wù)阻塞 (因?yàn)閽呙枞頃r(shí),一定也會讀到 OrderID=10248 的這一條記錄)。

下方的 SQL 語句,由于 OrderID 字段有設(shè)索引,因此下圖 1 的「執(zhí)行計(jì)劃」,會以算法中的「二分搜尋法」在索引中快速查找 OrderID=10250 的記錄

  1. SELECT * FROM Orders WHERE OrderID=10250  
  2. SELECT * FROM Orders WHERE OrderID=10250 AND ShipCountry='Brazil' 

圖 1 有正確使用到索引的 SQL 語句,以垂直的方向使用索引。用 AND 算符時(shí),只要有任一個(gè)字段有加上索引,就能受惠于索引的好處,并避免全表掃描

此時(shí)若我們將這句 SQL 語句,當(dāng)作前述會話 B 的語句,由于它和會話 A 所 UPDATE 的 OrderID=10248 不是同一條記錄,因此不會受會話 A 事務(wù)未回滾的影響,會話 B 能正常執(zhí)行 SELECT 語句。

但若我們將會話 B 的 SQL 語句,改用如下的 OR 算符,由于 ShipCountry 字段沒有加上索引,此時(shí)會造成全表掃描。如此一來,除了性能低落以外,還會因?yàn)樵谌頀呙钑r(shí),讀到會話 A 中鎖定的 OrderID=10248 那一條記錄,造成阻塞,讓會話 B 永遠(yuǎn)呈現(xiàn)「等待中」的狀態(tài).

  1. SELECT * FROM Orders WHERE OrderID=10250 OR ShipCountry='Brazil' 

圖 2 未正確使用索引的 SQL 語句,以水平的方向使用索引。用 OR 算符時(shí),必須「所有」用到的字段都有加上索引,才能真正有效使用索引、避免全表掃描

-------------------------------------------------------------------------------------------

發(fā)生阻塞時(shí),透過以下命令,可看出是哪個(gè)進(jìn)程 session id,阻塞了哪幾個(gè)進(jìn)程 session id,且期間經(jīng)過了多少「毫秒 (ms)」。如下圖 3 里 session id = 53 阻塞了 session id = 52 的進(jìn)程。另透過 SQL Server Profiler 工具,也能看到相同的內(nèi)容。

  1. SELECT blocking_session_id, wait_duration_ms, session_id FROM sys.dm_os_waiting_tasks 

圖 3 本帖前述會話 A 的 UPDATE 語句 (53),阻塞了會話 B 的 SELECT 語句 (52)

透過以下兩個(gè)命令,我們還能看到整個(gè)數(shù)據(jù)庫的鎖定和阻塞詳細(xì)信息:

  1. SELECT * FROM sys.dm_tran_locks  
  2. EXEC sp_lock 

圖 4 session id = 52 的 process 因阻塞而一直處于等待中 (WAIT)

另透過 KILL 命令,可直接殺掉造成阻塞的 process,如下:

KILL 53

-------------------------------------------------------------------------------------------

欲解決無限期等待的問題,除了前述的 SET LOCK_TIMEOUT 命令外,還有更省事的做法,如下,在會話 B 的 SQL 語句中,在表名稱后面加上 WITH (NOLOCK) 關(guān)鍵字,表示要求  SQL Server,不必去考慮這個(gè)表的鎖定狀態(tài)為何,因此也可減少「死鎖 (dead lock)」發(fā)生的機(jī)率。但 WITH (NOLOCK) 不適用 INSERT、UPDATE、DELETE。

  1. SELECT * FROM Orders WITH (NOLOCK) WHERE OrderID=10248 

類似的功能,也可如下,在 SQL 語句前,先設(shè)置「事務(wù)隔離級別」為可「臟讀 (dirty read)」。

  1. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
  2. SELECT * FROM Orders WHERE OrderID=10248 

兩種做法的效果類似,讓會話 B 即使讀到被鎖阻塞的記錄,也永遠(yuǎn)不必等待,但可能讀到別人未提交的數(shù)據(jù)。雖然說這種做法讓會話 B 不用請求共享鎖,亦即永遠(yuǎn)不會和其他事務(wù)發(fā)生沖突,但應(yīng)考慮項(xiàng)目開發(fā)實(shí)際的需求,若是會話 B 要查詢的是原物料的庫存量,或銀行系統(tǒng)的關(guān)鍵數(shù)據(jù),就不適合用這種做法,而應(yīng)改用第一種做法的 SET LOCK_TIMEOUT 命令,明確讓數(shù)據(jù)庫拋回等候逾時(shí)的錯(cuò)誤代號 1222,再自己寫代碼做處理。

-------------------------------------------------------------------------------------------

歸根究柢,我們在編程時(shí),就應(yīng)該避免寫出會造成長時(shí)間阻塞的 SQL 語句,亦即應(yīng)最小化鎖定爭用的可能性,以下為一些建議:

  • 盡可能讓事務(wù)輕薄短小、讓鎖定的時(shí)間盡量短,例如把不必要的命令移出事務(wù)外,或把一個(gè)大量更新的事務(wù),切成多個(gè)更新較少的事務(wù),以改善并發(fā)性。
  • 將組成事務(wù)的 SQL 語句,擺到一個(gè)「批 (batch) 處理」,以避免不必要的延遲。這些延遲常由 BEGIN TRAN ... COMMIT TRAN 命令之間的網(wǎng)絡(luò) I/O 所引起。
  • 考慮將事務(wù)的 SQL 語句寫在一個(gè)存儲過程內(nèi)。一般來說,存儲過程的執(zhí)行速度會比批處理的 SQL 語句快,且存儲過程可降低網(wǎng)絡(luò)的流量和 I/O,讓事務(wù)可更快完成。
  • 盡可能頻繁地認(rèn)可 Cursor 中的更新,因?yàn)?Cursor 的處理速度較慢,會讓鎖定的時(shí)間較長。
  • 若無必要,使用較寬松的事務(wù)隔離級別,如前述的 WITH (NOLOCK) 和 READ UNCOMMITTED。而非為了項(xiàng)目開發(fā)方便,全部使用默認(rèn)的 READ COMMITTED 級別。
  • 避免在事務(wù)執(zhí)行期間,還要等待用戶的反饋或交互,這樣可能會造成無限期的持有鎖定,如同本帖一開始提到的狀況,最后造成大量的阻塞和數(shù)據(jù)庫 connection 被占用。
  • 避免事務(wù) BEGIN TRAN 后查詢的數(shù)據(jù),可能在事務(wù)開始之前先被引用。
  • 避免在查詢時(shí) JOIN 過多的表,否則除了性能較差外,也很容易讀到正被鎖定或阻塞中的表和字段。
  • 應(yīng)注意在一個(gè)沒有索引的表上,過量的「行鎖」,或一些鎖定使用了過多的內(nèi)存和系統(tǒng)資源時(shí),SQL Server 為了有效地管理這些鎖定,會嘗試將鎖定擴(kuò)展為整個(gè)表的「表鎖」,此時(shí)會很容易造成其他 process 在訪問時(shí)的阻塞和等待。

原文標(biāo)題:快速搞懂 SQL Server 的鎖定和阻塞

鏈接:http://www.cnblogs.com/WizardWu/archive/2010/08/13/1798645.html

【編輯推薦】
  1. SQL Server數(shù)據(jù)庫和Oracle行轉(zhuǎn)列的特殊方案描述
  2. SQL Server行轉(zhuǎn)列的什么情況下被用?
  3. SQL Server實(shí)例中對另個(gè)實(shí)例的調(diào)用
  4. SQL Server identity列,美中不足之處
  5. SQL Server DateTime數(shù)據(jù)類型的另類解讀

 

責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2015-07-09 10:22:40

泥石流高精度預(yù)警技術(shù)

2016-11-10 20:18:16

Header Bidd程序化交易廣告

2015-06-19 13:38:25

2015-06-08 11:33:15

2011-07-07 13:08:49

2011-08-23 17:12:50

2018-09-12 11:07:55

2010-10-13 09:30:45

SQL Server

2011-02-18 17:31:18

SQL Server

2010-07-06 09:44:51

SQL Server數(shù)

2010-07-20 11:18:12

SQL server阻

2011-03-11 10:35:31

SQL鎖定SQL Server

2010-07-20 11:31:25

SQL Server避

2010-07-20 11:26:08

SQL Server阻

2014-11-17 09:47:03

2011-03-11 13:26:32

SQL ServerBlocking阻塞

2010-07-08 11:05:14

SQL Server數(shù)

2011-09-01 18:38:02

SQL Server 文件流功能

2021-07-07 11:55:51

SQL 內(nèi)存頁Windows

2013-02-01 14:07:40

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

亚洲综合中文字幕在线| 91超碰在线免费观看| 久操视频在线观看| 最新欧美精品一区二区三区| 亚洲成人一区二区三区| 欧美色图麻豆| 成人久久一区二区三区| 亚洲成在人线免费观看| 97国产精品视频| 国产精品一区二区美女视频免费看| 亚洲黄页视频免费观看| 日本高清在线观看wwwww色| 日韩欧美精品在线观看| 蜜桃传媒在线| 岛国av一区二区| 视频三区在线观看| 色婷婷亚洲一区二区三区| 青青视频在线观| 色噜噜狠狠成人网p站| 日韩写真福利视频在线| 午夜久久久久久久久| 天堂社区日本电影超碰| 舔着乳尖日韩一区| 天堂资源av| 欧美日韩中文字幕在线视频| 日本福利在线观看| 欧美日韩国产高清一区二区三区| 欧洲不卡av| 日韩精品在线免费播放| 国产后进白嫩翘臀在线观看视频| 91福利视频导航| 日本不卡二三区| 欧美一进一出视频| 国产精品最新自拍| 日韩精品一区二区三区四区五区| 欧美亚洲视频在线观看| 成人国产电影在线观看| 国内一区二区视频| 成人在线免费观看一区| av在线亚洲色图| 欧美专区中文字幕| 久久精品不卡| 国产一区二区视频在线免费观看 | 久久午夜老司机| www.com黄色片| 亚洲高清免费观看高清完整版在线观看| 伊人色综合久久| 精品国产电影一区二区| 国产精品亚洲成在人线| 日本高清视频精品| 国产精品亚洲产品| 丁香花在线影院观看在线播放| 国产精品嫩草影院com| 国产二区在线播放| 在线视频日本亚洲性| 在线观看欧美理论a影院| 精品国产一二| 成人av网址在线| 超碰97在线免费| 欧美一区二区三区免费观看视频| japanese23hdxxxx日韩| 国产成人91久久精品| 免费精品视频| jizz在亚洲| 欧美成人一级视频| 午夜欧洲一区| 欧美aaaaa喷水| 中文字幕乱码久久午夜不卡| 91青青在线视频| 欧美成人精品在线播放| 亚洲小说欧美另类社区| 99re在线视频免费观看| 欧美日韩不卡在线| 欧美精品密入口播放| 国产一区二区在线网站| 99国产精品久| 国产精品久久久久久福利| 97精品伊人久久久大香线蕉| 玖玖国产精品视频| 最新中文字幕在线观看| 久久久91精品国产一区不卡| 国产精品九九| 久久久精品麻豆| 91精品国产综合久久久久| av日韩精品| 日本xxxxx18| 91久久精品一区二区二区| 99国内精品久久久久| 青青影院一区二区三区四区| 一区二区三区美女视频| 欧美另类激情| 中日韩在线视频| 欧美色欧美亚洲另类二区| 高清一区二区三区| 99er在线视频| 精品国产免费人成电影在线观看四季| 天天综合精品| 免费羞羞视频| 久久久av网站| 激情综合色播激情啊| av在线天堂播放| 国产精品男女猛烈高潮激情| 91毛片在线观看| 极品视频在线| 日韩av在线一区二区三区| 性做久久久久久久久| 国产伦精品一区二区三区在线播放 | 成人动漫在线免费观看| 欧美资源在线观看| 久久久五月婷婷| 成人黄色在线| 在线视频欧美一区| 欧美va天堂va视频va在线| 国产精品porn| 岛国在线大片| 国产欧美亚洲日本| 精品日韩视频在线观看| 神马久久av| av成人网在线| 国产成人a亚洲精品| 国产精品久久久久久久久免费樱桃| 免费观看国产视频在线| 一区国产精品视频| 国产日本精品| av在线1区2区| zzijzzij亚洲日本成熟少妇| 91久久久精品国产| 日韩电影天堂视频一区二区| 成人免费一区二区三区在线观看| √最新版天堂资源网在线| 国产在线不卡精品| 国产精品一区免费视频| 成人av电影观看| 国产一区二区三区视频| 国产剧情一区二区在线观看| 亚洲五码中文字幕| 久久久999精品| 国产一区二区h| 神马久久午夜| 亚洲高潮无码久久| 亚洲一二在线观看| eeuss鲁片一区二区三区在线观看| 高清电影一区| 欧美日韩一区二区在线免费观看| 久久综合五月天| 亚洲欧美在线视频| 日本久久精品| 九九在线视频| 日韩精品伦理第一区| 亚洲国产91色在线| 不卡一二三区首页| 久久久精品国产**网站| 成人xxxx| 久久精品中文字幕一区二区三区 | 玛雅亚洲电影| 日本精品免费在线观看| 久久影视电视剧免费网站| 久久精品免视看| 视频一区欧美| 老司机免费在线视频| 色一情一乱一乱一区91| 九九热在线精品视频| 亚洲va中文字幕| 日韩不卡在线观看日韩不卡视频| 啊啊啊久久久| 在线观看免费网站黄| www.射射射| 欧美中日韩免费视频| 欧美专区中文字幕| 久久久久久久久久国产精品| 亚洲日韩欧美视频| 午夜欧美一区二区三区在线播放| 亚洲精品在线二区| 97一区二区国产好的精华液| 蜜桃一区二区| 免费看污污网站| 国产精品香蕉国产| 日韩一级免费观看| 91网站在线播放| 日韩一区二区在线| sqte在线播放| 日韩中文字幕在线视频播放| 亚洲护士老师的毛茸茸最新章节| 亚洲国产一二三| 欧美中文日韩| 欧美freesex交免费视频| 99热这里只有精品首页| hbad中文字幕| 亚洲美女欧洲| 91麻豆国产香蕉久久精品| 日韩极品在线| 中文字幕在线三区| 香港日本韩国三级网站| www久久99| 欧美日韩高清一区二区三区| 精品成人一区二区三区| 亚洲综合男人的天堂| 久久九九影视网| 九一久久久久久| 亚洲资源av|