主頁 > 資料庫 > 【SQL SERVER】鎖機制

【SQL SERVER】鎖機制

2020-09-11 12:06:31 資料庫

鎖定是 SQL Server 資料庫引擎用來同步多個用戶同時對同一個資料塊的訪問的一種機制,

  1. 基本概念
  2. 利用SQL Server Profiler觀察鎖
  3. 死鎖產生的原因及避免
  4. 總結

基本概念

資料庫引擎隔離級別

隔離級別定義
未提交的讀取 隔離事務的最低級別,只能保證不讀取物理上損壞的資料, 在此級別上,允許臟讀,因此一個事務可能看見其他事務所做的尚未提交的更改
已提交的讀取 允許事務讀取另一個事務以前讀取(未修改)的資料,而不必等待第一個事務完成, SQL Server 資料庫引擎保留寫鎖(在所選資料上獲取)直到事務結束,但是一執行 SELECT 操作就釋放讀鎖, 這是SQL Server 資料庫引擎默認級別
可重復的讀取 SQL Server 資料庫引擎保留在所選資料上獲取的讀鎖和寫鎖,直到事務結束, 但是,因為不管理范圍鎖,可能發生虛擬讀取
可序列化 隔離事務的最高級別,事務之間完全隔離, SQL Server 資料庫引擎保留在所選資料上獲取的讀鎖和寫鎖,在事務結束時釋放它們, SELECT 操作使用分范圍的 WHERE 子句時獲取范圍鎖,主要為了避免虛擬讀取
 

鎖粒度

資源說明
RID 用于鎖定堆中的單個行的行識別符號,也就是常說的行鎖
KEY 索引中用于保護可序列化事務中的鍵范圍的行鎖
PAGE 資料庫中的 8 KB 頁,例如資料頁或索引頁,也就常說的業級鎖
EXTENT 一組連續的八頁,例如資料頁或索引頁
HoBT 堆或 B 樹, 用于保護沒有聚集索引的表中的 B 樹(索引)或堆資料頁的鎖
TABLE 包括所有資料和索引的整個表
FILE 資料庫檔案
APPLICATION 應用程式專用的資源
METADATA 元資料鎖
ALLOCATION_UNIT 分配單元
DATABASE 整個資料庫
 

鎖型別

說明
共享 (S) 用于不更改或不更新資料的讀取操作,如 SELECT 陳述句
更新 (U) 用于可更新的資源中, 防止當多個會話在讀取、鎖定以及隨后可能進行的資源更新時發生常見形式的死鎖
排他 (X) 用于資料修改操作,例如 INSERT、UPDATE 或 DELETE, 確保不會同時對同一資源進行多重更新
意向 (I) 用于建立鎖的層次結構, 意向鎖包含三種型別:意向共享 (IS)、意向排他 (IX) 和意向排他共享 (SIX)
架構 (Sch-) 在執行依賴于表架構的操作時使用, 架構鎖包含兩種型別:架構修改 (Sch-M) 和架構穩定性 (Sch-S)
大容量更新 (BU) 在將資料大容量復制到表中且指定了 TABLOCK 提示時使用
鍵范圍 (Range) 當使用可序列化事務隔離級別時保護查詢讀取的行的范圍, 確保再次運行查詢時其他事務無法插入符合可序列化事務的查詢的行
 

利用SQL Server Profiler觀察鎖

1. 準備資料10條資料

create table DataTable(Id int identity(1,1), [Name] varchar(50), [Address] varchar(200), CreateTime datetime2)
    
insert into DataTable
select 'Wilson','廣東省廣州市',GETDATE() union all
select 'Alice','北京市朝陽區',GETDATE() union all
select 'Miksovsky','吉林省松原市',GETDATE() union all
select 'Hines','甘肅省蘭州市',GETDATE() union all
select 'Kane','遼寧省沈陽市',GETDATE() union all
select 'Gode','湖北省荊州市',GETDATE() union all
select 'Chen','湖南省岳陽市',GETDATE() union all
select 'Trenary','福建省廈門市',GETDATE() union all
select 'Achong','廣西省玉林市',GETDATE() union all
select 'Nixon','江西省景德鎮',GETDATE() 
View Code

2. 打開SQL Server Profiler選中鎖事件,勾選type和mode,建議取消不需要觀察的列,然后用列篩選器過濾要觀察的DB

3. 查詢資料

 可以看到在頁面級別加上意向共享鎖,因為我們資料只有一頁

4. 更新一條資料

1. 表上加上意向排它鎖(IX),可以用select OBJECT_NAME(581577110) 查看objectid代表的東西

2. 頁級別加上意向更新鎖(IU),告訴SQL Server引擎這里有更新鎖

3. 獲取第一行的更新鎖(U),這里條件匹配

4. 頁級別升級為意向排他鎖(IX), 告訴SQL Server引擎這里有排他鎖

5. 第一個行更新鎖 升級為排它鎖(X)

6. 釋放鎖

7. 隨條掃描后面的記錄,只是條件不符合,也就不會升級鎖級別

 

可以看到是全表掃描,因為沒聚集索引(堆表),我們也沒做一個主鍵,下面將Id添加主鍵然后再更新試試

alter table DataTable add constraint PK_DataTable primary key(Id asc)

 可以看出,直接在表,頁級別加上意向排它鎖(IX),然后在鍵上加上排它鎖(X)

因為這里我們用主鍵更新,而且SQL Server主鍵默認是聚集索引,如果指定是非聚集索引主鍵,這里也會經歷更新鎖 到 排他鎖,有興趣的可以自行驗證

 

5. 洗掉一條資料

 這次我們沒用主鍵洗掉,程序和更新的第一種情況差不多,就不列了,

因為加了聚集索引,索引定位器執行聚集索引Key的hash,要驗證是否那條記錄,可以在洗掉前加上%%lockres%%去查

 

死鎖產生的原因及避免

死鎖產生的原因

微軟檔案是這樣說

在兩個或多個任務中,如果每個任務鎖定了其他任務試圖鎖定的資源,此時會造成這些任務永久阻塞,從而出現死鎖

我理解就是有2個事務回圈依賴對方的資源導致產生死鎖,

例如

1. 事務A 獲取 Row1 資源

2. 事務B 獲取 Row2 資源

3. 事務A獲取Row2資源,由于這時Row2是被事務B占有,所以必須等事務B完成

4. 事務B獲取Row1資源,由于這時Row1是被事務A占有,所以必須等事務A完成

SQL Server處理死鎖策略

1. 定期檢查陷入死鎖的任務

2. 若檢查到回圈依賴

3. 選擇其中一個作為犧牲品,然后終止事務,然另外一個得以完成

模擬死鎖

分別在兩個不同的會話執行下面陳述句

begin tran;

update DataTable set Address = '上海市' where Id = 2;
--延遲5秒執行
WAITFOR DELAY '00:00:05';
update DataTable set Address = '上海市' where Id = 3;

commit;
begin tran;

update DataTable set Address = '上海市' where Id = 3;
--延遲5秒執行
WAITFOR DELAY '00:00:05';
update DataTable set Address = '上海市' where Id = 2;

commit;

執行一段時間,其中一個會出現下面錯誤

SQL Server Profiler 捕獲死鎖分析

打開Locks事件的死鎖圖形

 

 重新執行上面陳述句,模擬死鎖,Profiler捕獲到死鎖

 

可以看出

1. 行程56 請求的Key 的排它鎖  被行程 54 占有

2. 行程54 請求的Key 的排他鎖 被行程 56 占有

3. 形成了回圈依賴

我們這里的Sql比較簡單,而且沒有用引數化執行,所以我們指定是哪一行被鎖,線上的通常不能直接看到哪一行被鎖

我們可以通過xml查看等待的資源,在xml里面有process-list 下面有多個process,process節點上面有個waitresource屬性,這個指出每個行程等待的資源

鎖型別:db_id : hobt_id : (hashvalue)

KEY: 6:72057594043760640 (61a06abd401c)

通過%%lockres%% 查到被鎖資源

select %%lockres%%,* from DataTable where %%lockres%% = '(98ec012aa510)'

鎖型別不一樣,得到的會不一樣,根據各自的格式用db_name / object_name  / dbcc去查到當前被鎖的資源,有時候需要利用DBCC查詢Page存盤頁面,可以參考上一篇文章【SQL SERVER】資料內部存盤結構簡單探索

避免死鎖

首先需要說明死鎖不能完全避免,但遵守特定的編碼慣例可以將發生死鎖的機會降至最低

1. 按同一順序訪問物件,一個獲取鎖,另外一個就必須等待

2. 避免事務中的用戶互動 ,這樣導致事務時間過長,容易造成死鎖

3. 保持事務簡短并處于一個批處理中,道理和2一樣,盡量讓事務運行時間短,

4. 使用較低的隔離級別,這個看能不能接受臟讀,幻讀等副作用

總結

1. 鎖機制保證并發情況下的資料訪問,

2. 開發中應該盡量利用索引檢索資料,特別是UPDATE/DELETE這種需要排它鎖,應該利用唯一聚集索引欄位更新(通常是主鍵)

3. 規范使用事務能減少死鎖發生

轉發請標明出處:https://www.cnblogs.com/WilsonPan/p/12618849.html

參考文章

事務鎖定和行版本控制指南 - SQL Server | Microsoft Docs

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/5556.html

標籤:SQL Server

上一篇:常用SQL Server進行性能優化陳述句

下一篇:【SQL SERVER】索引

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more