We all know that Scan to look for data is bad, but you know this in SQL implementation, how much will the Lock took it?
We can from SQL Profiler in Lock: Oh, to observe Released: Acquired and Lock!
Recently I saw "two transactions update a heap table encounter strange deadlock" in Theory.
It makes me think of the strong brother said before on TechDay, when you think SQL Update, you must be Row Lock it?
When a Table is not established any Index, the data to be updated is to find a pen, the solution is the establishment of index data break!
Test Script strong brother follows (using TSQL2012),
--SESSION I
USE TSQL2012
GO
IF OBJECT_ID('employees') IS NOT NULL
DROP TABLE employees
GO
SELECT *
INTO employees
FROM [HR].[Employees]
GO
SELECT *
FROM [dbo].[employees]
BEGIN TRANSACTION
UPDATE [dbo].[employees]
SET [firstname] = [firstname] + '@'
WHERE empid = 1
SELECT *
FROM [dbo].[employees]
WHERE empid = 1
--ROLLBACK
--SESSION 2
SELECT *
FROM [dbo].[employees]
WHERE empid = 2
--WHERE lastname='Funk'
--solution
DROP INDEX IDX_SPLIT ON [dbo].[employees]
CREATE CLUSTERED INDEX IDX_SPLIT ON [dbo].[employees]
([empid] DESC,[lastname] ASC )
GO
That situation is similar to this question, Script as follows,
USE tempdb
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table1](
[A] [nvarchar](10) NULL,
[B] [nvarchar](10) NOT NULL,
[C] [nvarchar](10) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa1', N'b1', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa2', N'b3', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b4', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b5', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b2', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b6', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b7', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b8', N'11')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa1', N'b9', N'11')
Open two query window, execute a query first, and then cut to the second query execution,
--查询1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
UPDATE table1
SET A = 'aa1'
WHERE B = 'b3'
EXEC sp_lock @@spid
WAITFOR DELAY '00:00:10'
UPDATE table1
SET A = 'aa2'
WHERE B = 'b8'
EXEC sp_lock @@spid
WAITFOR DELAY '00:00:10'
COMMIT TRAN
--查询2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
UPDATE table1
SET A = 'aa3'
WHERE B = 'b1'
EXEC sp_lock @@spid
COMMIT TRAN
And so all of a sudden, the inquiry will be sacrificed 2, as follows,
Msg 1205, Level 13, State 45, Line 3
Transaction (Process ID 117) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Msg 1205, Level 13, State 45 , Line 3
transaction (Processing Sequence Identification code 117) on the lock resource is locked and another process sequence has been selected as the deadlock victim. Please re-executing the transaction.
FIG DeadLock follows,
sp_lock information as follows,
Update time, because without any index, so you Scan way is as follows,
So, it will be to find a pen, first obtain Update Lock, non-compliance with Rease Update Lock, and then remove the pen, that meet, they get Exclusive Lock.
The second query will wait because they want to get Update Lock, and the sum of the data to be queried Exclusive Lock 1 made up!
So ... this situation is to create Index it can be found immediately, without the need to use Scan way to go, caused by waiting for the Lock,
CREATE NONCLUSTERED INDEX nidx_table1_B
ON table1(B);
And after the establishment of the index, you can find, not transaction-sweep, but will be directed towards Update and Exclusive Lock pen and then modify the data After the data, Release Lock! Follows,
Reference data
Using a Clustered Index to Solve a SQL Server Deadlock Issue
Two transactions update a heap table encounter strange deadlock
Original: Large column [SQL] to avoid the establishment of Index DeadLock