Cause and solution of SQL Server database deadlock

Source: Internet
Author: User
The SQL Server database deadlock is generally caused by two or more trans requesting a specific actual application object being requested by the other party, resulting in mutual waiting. A simple example is as follows:

The SQL Server database deadlock is generally caused by two or more trans requesting a specific actual application object being requested by the other party, resulting in mutual waiting. A simple example is as follows:

SQL server deadlock 1:

A user A accesses Table A (locking table A) and then accesses Table B
Another user B accesses table B (Table B is locked) and then attempts to access Table
At this time, user A has locked table B because user B has to wait for user B to release table B to continue. Well, the old man will have to wait honestly.
Similarly, user B has to wait for user A to release Table A to continue.
SQL server deadlock solution:
This deadlock is caused by bugs in your program. There is no other way to adjust the logic of your program.
Carefully analyze the logic of your program,
1: Try to avoid locking two resources at the same time
2: When two resources must be locked at the same time, ensure that the resources should be locked in the same order at any time.
  
SQL server deadlock performance 2:

User A reads A record and modifies it.
This is the record modified by user B.
Here, the nature of the lock in user A's transaction is increased from the share lock attempt to the exclusive lock (for update), and the exclusive lock in user B is caused by the existence of A share lock

Must wait for A release
The shared lock is released, and the exclusive lock that A cannot rise due to the exclusive lock of B cannot be released, so A deadlock occurs.
Such deadlocks are relatively hidden, but they often occur in projects that are a little larger.
SQL server deadlock solution:
Let user A's transactions (that is, the first read and then write operations), In the select statement, Update lock is used.
Syntax:
Select * from table1 with (updlock) where ....


SQL Server deadlock Check Tool

The Code is as follows:


If exists (select * from dbo. sysobjects where id = object_id (n' [dbo]. [sp_who_lock] ') and

OBJECTPROPERTY (id, n' IsProcedure ') = 1)
Drop procedure [dbo]. [sp_who_lock]
GO


Use master
Go
Create procedure sp_who_lock
As
Begin
Declare @ spid int, @ bl int,
@ IntTransactionCountOnEntry int,
@ IntRowcount int,
@ IntCountProperties int,
@ IntCounter int

Create table # tmp_lock_who (
Id int identity (1, 1 ),
Spid smallint,
Bl smallint)

IF @ ERROR <> 0 RETURN @ ERROR

Insert into # tmp_lock_who (spid, bl) select 0, blocked
From (select * from sysprocesses where blocked> 0)
Where not exists (select * from sysprocesses where blocked> 0) B
Where a. blocked = spid)
Union select spid, blocked from sysprocesses where blocked> 0

IF @ ERROR <> 0 RETURN @ ERROR

-- Find the number of records in the temporary table
Select @ intCountProperties = Count (*), @ intCounter = 1
From # tmp_lock_who

IF @ ERROR <> 0 RETURN @ ERROR

If @ intCountProperties = 0
Select 'no blocking and deadlock information' as message

-- Start of Loop
While @ intCounter <= @ intCountProperties
Begin
-- Retrieve the first record
Select @ spid = spid, @ bl = bl
From # tmp_lock_who where Id = @ intCounter
Begin
If @ spid = 0
Select '+ CAST (@ bl as varchar (10) +' causes database deadlock. The SQL statement executed by 'process No. 'is AS follows'
Else
Select 'process No. SPID: '+ CAST (@ spid as varchar (10) + 'be' + 'process No. SPID:' + CAST (@ bl AS VARCHAR

(10) + 'blocking, the SQL syntax executed by the current process is as follows'
Dbcc inputbuffer (@ bl)
End

-- Move the loop pointer down
Set @ intCounter = @ intCounter + 1
End


Drop table # tmp_lock_who

Return 0
End

Deadlock handling method:

(1) check that the spid is in the wait status according to the SQL statement provided in 2, and then kill the spid (that is, the fourth necessary condition for cracking the deadlock: loop

Wait); of course, this is only a temporary solution. We can't check the deadlock and Kill sp in the user's production environment when a deadlock occurs. We should

Consider how to avoid deadlocks.

(2) Use SET LOCK_TIMEOUT timeout_period (unit: milliseconds) to SET lock request timeout. By default, the database does not have a timeout period.

The Code is as follows:

(The value of timeout_period is-1. You can use SELECT @ LOCK_TIMEOUT to view the value, that is, wait for an indefinite period ). When the request lock exceeds timeout_period

Will return an error. When the timeout_period value is 0, the message is returned when the lock is encountered. Set lock request timeout, break the deadlock

Two necessary conditions (request and retention conditions ).

Server: Message 1222, level 16, status 50, Row 1
The lock request timeout period has been exceeded.


(3). There is a lock Monitor thread in SQL Server to execute the deadlock check. When the lock Monitor starts the deadlock search for a specific thread, it will identify that the thread is waiting.

Then, find the owner of a specific resource and recursively execute the deadlock search for those threads until a loop that constitutes the deadlock condition is found.

. After a deadlock is detected, the database engine selects the Session of the transaction with the smallest rollback and rollback transactions as the deadlock victim, Returns Error 1205, and rolls back the deadlock at the sacrifice.

And release all the locks held by the transaction, so that transactions in other threads can request resources and continue to run.

Deadlock example and Solution
5.1 SQL deadlock
(1). Basic data for testing:

The Code is as follows:

Create table Lock1 (C1 int default (0 ));
Create table Lock2 (C1 int default (0 ));
Insert into Lock1 VALUES (1 );
Insert into Lock2 VALUES (1 );


(2) open two query windows and execute the following two SQL statements:

The Code is as follows:

-- Query 1
Begin Tran
Update Lock1 Set C1 = C1 + 1;
WaitFor Delay '00: 01: 00 ';
SELECT * FROM Lock2
Rollback Tran;


-- Query 2
Begin Tran
Update Lock2 Set C1 = C1 + 1;
WaitFor Delay '00: 01: 00 ';
SELECT * FROM Lock1
Rollback Tran;

The preceding SQL statement WaitFor Delay '00: 01: 00' is used to wait for 1 minute to check the lock.


Solution
A). SQL Server automatically selects an SQL statement as the deadlock victim: after running the two queries above, we will find that one SQL statement can be executed normally,

Another SQL statement reports the following error:

Server: Message 1205, Level 13, status 50, Row 1
The transaction (process ID xx) and the other process have been deadlocked on the lock resource, and the transaction has been selected as the deadlock victim. Run the transaction again.
This is the lock monitor described in section 4 above.

B). access objects in the same order: reversing the order of Update and SELECT statements in any SQL statement. For example, modify the second SQL statement as follows:

The Code is as follows:

-- Query2
Begin Tran
SELECT * FROM Lock1 -- apply for S lock on Lock1
WaitFor Delay '00: 01: 00 ';
Update Lock2 Set C1 = C1 + 1; -- Lock2: RID: X
Rollback Tran;


Of course, this modification also has a price. This will cause the second SQL to remain in the blocking state until the execution of the first SQL statement is completed. Execute Query1 or

Query2 takes about 1 minute, but if Query2 is executed immediately when Query1 is executed, Query2 takes 2 minutes to complete.

The requested resources Reduce the concurrency to a certain extent.

C) when the SELECT statement is added With (NoLock), the prompt is: by default, the SELECT statement will apply the S lock (shared lock) to the queried resource, and the S lock and X lock (exclusive lock) will not

Compatible; but With (NoLock), SELECT does not lock the queried resources (or apply the Sch-S lock, the Sch-S lock can be compatible With any lock );

These two sqls can concurrently access the same resource. Of course, this method is suitable for solving read and write concurrency deadlocks, but adding With (NoLock) may cause

Dirty read.

The Code is as follows:

SELECT * FROM Lock2 WITH (NOLock)
SELECT * FROM Lock1 WITH (NOLock)

D) Use a lower isolation level. SQL Server 2000 supports four transaction isolation levels (TIL): READ UNCOMMITTED and READ

Snapshot til is added to COMMITTED, repeatable read, and SERIALIZABLE; SQL Server 2005. By default

With read committed til, we can add a set transaction isolation level read statement before the preceding two SQL statements.

UNCOMMITTED to reduce the TIL to avoid deadlocks. In fact, the SELECT statement in the transaction that runs in read uncommitted til is not the result asset.

The source locks or Sch-S locks instead of S locks. However, you need to note that read uncommitted til allows dirty reads, although it reduces the level of TIL.

The preceding two SQL statements do not report errors during execution, but the execution result is one return 1 and one returns 2, that is, the dirty data is read.

It is what we expect.

E). Add SET LOCK_TIMEOUT timeout_period before SQL. When the request lock exceeds the SET timeout_period time, the current SQL

Execute, sacrifice yourself, and fulfill others.

F). Use the row-based version control isolation level (supported by SQL Server 2005): After the following options are enabled, SELECT does not apply the S lock to the requested resources,

No locks or Sch-S locks are applied to minimize the chance of deadlocks between read and write operations, and dirty reads are not performed. Ah

SET ALLOW_SNAPSHOT_ISOLATION ON
SET READ_COMMITTED_SNAPSHOT ON

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.