1. --死鎖
2. /**********************************************************************************************************************
3. 死鎖指兩個以上事務相互阻塞相互等待對方釋放它們的鎖,SQL Server會通過回滾其中一個事務並返回一個錯誤來自已解決阻塞問題,
4. 讓其他事務完成它們的工作。
5.
6. 整理人:中国风(Roy)
7.
8. 日期:2008.07.20
9. ***********************************************************************************************************************/
10.
11. set nocount on ;
12. if object_id('T1') is not null
13. drop table T1
14. go
15. create table T1(ID int primary key,Col1 int,Col2 nvarchar(20))
16. insert T1 select 1,101,'A'
17. insert T1 select 2,102,'B'
18. insert T1 select 3,103,'C'
19. go
20.
21. if object_id('T2') is not null
22. drop table T2
23. go
24. create table T2(ID int primary key,Col1 int,Col2 nvarchar(20))
25. insert T2 select 1,201,'X'
26. insert T2 select 2,202,'Y'
27. insert T2 select 3,203,'Z'
28.
29.
30. go
31. 生成表數據:
32. /*
33. T1:
34. ID Col1 Col2
35. ----------- ----------- --------------------
36. 1 101 A
37. 2 101 B
38. 3 101 C
39.
40. T2:
41. ID Col1 Col2
42. ----------- ----------- --------------------
43. 1 201 X
44. 2 201 Y
45. 3 201 Z
46. */
47.
48. 防止死鎖:
49. 1、 最少化阻塞。阻塞越少,發生死鎖機會越少
50. 2、 在事務中按順序訪問表(以上例子:死鎖2)
51. 3、 在錯誤處理程式中檢查錯誤1205並在錯誤發生時重新提交事務
52. 4、 在錯誤處理程式中加一個過程將錯誤的詳細寫入日誌
53. 5、 索引的合理使用(以上例子:死鎖1、死鎖3)
54. 當發生死鎖時,事務自動提交,可通過日誌來監視死鎖
55.
56.
57. 死鎖1(索引):
58. --連接窗口1
59. --1步:
60. begin tran
61. update t1 set col2=col2+'A' where col1=101
62.
63. --3步:
64. select * from t2 where col1=201
65. commit tran
66.
67.
68. --連接窗口2
69.
70. --2步:
71. begin tran
72. update t2 set col2=col2+'B' where col1=203
73.
74. --4步:
75. select * from t1 where col1=103
76. commit tran
77.
78.
79.
80. --連接窗口1:收到死鎖錯誤,連接窗口2得到結果:
81.
82. /*
83. 訊息 1205,層級 13,狀態 51,行 3
84. 交易 (處理序識別碼 53) 在 鎖定 資源上被另一個處理序鎖死並已被選擇作為死結的犧牲者。請重新執行該交易。
85. */
86.
87. --連接窗口2:得到結果
88.
89. /*
90. ----------- ----------- --------------------
91. 3 103 C
92. */
93.
94. 處理方法:
95. --在t1、t2表的col1條件列建索引
96. create index IX_t1_col1 on t1(col1)
97. create index IX_t2_col1 on t2(col1)
98. go
99.
100. --連接窗口1
101. --1步:
102. begin tran
103. update t1 set col2=col2+'A' where col1=101
104.
105. --3步:
106. select * from t2 with(index=IX_t2_col1)where col1=201 --因表數據少,只能指定索引提示才能確保SQL Server使用索引
107. commit tran
108.
109.
110.
111. --連接窗口2
112.
113. --2步:
114. begin tran
115. update t2 set col2=col2+'B' where col1=203
116.
117.
118. --4步:
119. select * from t1 with(index=IX_t1_col1) where col1=103 --因表數據少,只能指定索引提示才能確保SQL Server使用索引
120. commit tran
121.
122.
123.
124. --連接窗口1:
125. /*
126. ID Col1 Col2
127. ----------- ----------- --------------------
128. 1 201 X
129.
130. (1 個資料列受到影響)
131.
132. */
133. --連接窗口2
134. /*
135. ID Col1 Col2
136. ----------- ----------- --------------------
137. 3 103 C
138.
139. (1 個資料列受到影響)
140. */
141.
142.
143. 死鎖2(訪問表順序):
144.
145. --連接窗口1:
146. --1步:
147. begin tran
148. update t1 set col1=col1+1 where ID=1
149.
150. --3步:
151. select col1 from t2 where ID=1
152. commit tran
153.
154.
155.
156. --連接窗口2:
157. --2步:
158. begin tran
159. update t2 set col1=col1+1 where ID=1
160.
161. --4步
162. select col1 from t1 where ID=1
163. commit tran
164.
165.
166. --連接窗口1:
167.
168. /*
169. col1
170. -----------
171. 201
172.
173. (1 個資料列受到影響)
174. */
175.
176. --連接窗口2:
177.
178. /*
179. col1
180. -----------
181. 訊息 1205,層級 13,狀態 51,行 1
182. 交易 (處理序識別碼 54) 在 鎖定 資源上被另一個處理序鎖死並已被選擇作為死結的犧牲者。請重新執行該交易。
183. */
184.
185. 處理方法:
186.
187. --改變訪問表的順序
188.
189. --連接窗口1:
190. --1步:
191. begin tran
192. update t1 set col1=col1+1 where ID=1
193.
194. --3步:
195. select col1 from t2 where ID=1
196. commit tran
197.
198. --連接窗口2:
199. --2步:
200. begin tran
201. select col1 from t1 where ID=1--會等待連接窗口1提交
202. --4步
203. update t2 set col1=col1+1 where ID=1
204. commit tran
205.
206. 死鎖3(單表):
207.
208. --連接窗口1:
209.
210. while 1=1
211. update T1 set col1=203-col1 where ID=2
212.
213. --連接窗口2:
214. declare @i nvarchar(20)
215. while 1=1
216. set @i=(select col2 from T1 with(index=IX_t1_col1)where Col1=102);--因表數據少,只能指定索引提示才能確保SQL Server使用索引
217.
218. --連接窗口1
219. /*
220. 訊息 1205,層級 13,狀態 51,行 4
221. 交易 (處理序識別碼 53) 在 鎖定 資源上被另一個處理序鎖死並已被選擇作為死結的犧牲者。請重新執行該交易。
222. */
223.
224.
225. 處理方法:
226. 1、刪除col1上的非聚集索引,這樣影響SELECT速度,不可取.
227. drop index IX_t1_col1 on t1
228. 2、建一個覆蓋索引
229. A、drop index IX_t1_col1 on t1
230. B、create index IX_t1_col1_col2 on t1(col1,col2)
231.
232.
233. 通過SQL Server Profiler查死鎖信息:
234.
235. 啟動SQL Server Profiler——連接實例——事件選取範圍——顯示所有事件
236. 選擇項:
237. TSQL——SQL:StmtStarting
238. Locks——Deadlock graph(這是SQL2005新增事件,生成包含死鎖信息的xml值)
239. ——Lock:DeadlockChain 死鎖鏈中的進程產生該事件,可標識死鎖進程的ID並跟蹤操作
240. ——Lock:Deadlock 該事件發生了死鎖
241.
分享到:
相关推荐
2015 Oracle 技术嘉年华(OTN)分会场11何登成 - 管中窥豹——MySQL(InnoDB)死锁分析之道
我们提出了一种针对参与者模型的通信死锁分析的独特方法,该方法的分析结果偏低。 我们的分析通过在称为从属依赖关系图的新型依赖关系图中找到循环依赖关系来检测狭窄定义的通信死锁。 从属依赖关系图基于Actor之间...
1.1 一个不可思议的死锁 1 1.1.1 初步分析 3 1.2 如何阅读死锁日志 3 2.1 Delete操作的加锁逻辑 4 2.2 死锁预防策略 5 2.3
该文档详细分析了innodb的加锁原理、死锁原因以及处理方式
数据库死锁分析.doc
管中窥豹——MySQL(InnoDB)死锁分析之道 阿里巴巴高级数据库专家
mysql死锁分析
并发访问ORACLE数据库的数据死锁分析和解决措施.pdf
半导体制造中多组合设备的Petri网建模及死锁分析.pdf
背景pop购药上线后解冻操作经常发生死锁,报错日志如下:死锁sql语句select id from order_pay_statusupdate order_p
基于板材柔性制造系统模型RBOPN所具有的可以完全描述FMS的动态行为以及系统中相关对象子网之间关系的分析能力,提出一种死锁检查分析方法。...实例分析表明,该死锁分析方法简化了计算分析过程,提高了工作效率。
SQL死锁监控工具
在实际开发中,经常有初学的开发人员,由于对事务机制不熟悉,导致后台死锁,这可能导致用户大面积瘫痪,为了让技术人员快速的找到问题所在的机器,本人最近开发了一个简单的数据死锁查询工具,在我的项目上能快速的...
SQL Server 2000中的死锁分析。
遇到ANR(Application Not Responding)是比较常见的问题,产生ANR的原因有很多,比如CPU使用过高、事件没有得到及时的响应、死锁等,下面将通过一次因为死锁导致的ANR问题,来说明如何通过trace文件分析ANR问题
线程死锁 CPU过高 WeakHashMap 请求原因分析
Sqlserver分析死锁进程,分析死锁的进程ID号
db2死锁问题分析及解决方案,可以快速解决数据库问题。
oracle死锁故障分析和诊断解决~~~~~~~~~
NULL 博文链接:https://beijingwo2008.iteye.com/blog/1851542