sql server 死锁简易例子2--可通过索引优化解决死锁问题

工作些年,常听见的一名话是

“死锁是程序问题,不能通过优化数据库来解决死锁,必须要改写程序,做好事务与访问顺序方面的控制”

如果产生死锁的业务模块频繁访问大量堆表,通过数据库优化是在一定的概率下可以解决死锁问题的,实际工作中,大概有百分四十的概率可以通过优化索引解决死锁问题。

死锁概念产生原理在csdn上的很多。

在这里举个通过索引优化解决死锁问题的简单栗子,证明我来过...

窗口1:创建测试表

USE [test]
GO
/****** Object:  Table [dbo].[t2]    Script Date: 2018/5/29 18:52:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[t2](
	[f1] [int] NULL,
	[f2] [int] NULL
) ON [PRIMARY]

GO
/****** Object:  Index [i2]    Script Date: 2018/5/29 18:52:46 ******/
CREATE CLUSTERED INDEX [i2] ON [dbo].[t2]
(
	[f1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
INSERT [dbo].[t2] ([f1], [f2]) VALUES (1, 1)
GO
INSERT [dbo].[t2] ([f1], [f2]) VALUES (1, 2)
GO
INSERT [dbo].[t2] ([f1], [f2]) VALUES (2, 1)
GO
INSERT [dbo].[t2] ([f1], [f2]) VALUES (2, 2)
GO


窗口2:查询1

--execute 1
begin tran
--execute 1
update t2 set f1=f1 where f1=1 and f2=1
--execute 3
select * from t2 where f1=2 and f2=2
--execute 5
rollback
窗口2:查询2
--execute 2
begin tran
--execute 2
update t2 set f1=f1 where f1=2 and f2=1
--execute 4
select * from t2 where f1=1 and f2=2
--execute 6
rollback

按照注释execute 1、2、3、4、5、6依次选中运行

执行到第四步,sql server自动检测到死锁并kill 之


至此窗口2,3运行rollback释放锁。

解决办法

通过添加正确索引来以免本例子中的update过度锁数据。

CREATE NONCLUSTERED INDEX [i3] ON [dbo].[t2]
(
	[f1] ASC,
	[f2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
按照注释execute 1、2、3、4、5、6依次选中运行

执行到第四步,不会死锁,正常返回结果。


最后execute 5、6

Rollback

猜你喜欢

转载自blog.csdn.net/wangzhpwang/article/details/80500380