Created
May 23, 2017 14:04
-
-
Save EtherZa/6cfccfc54d4983cc8d8f2f007b5231b5 to your computer and use it in GitHub Desktop.
Simulate a SQL deadlock (Source: https://stackoverflow.com/questions/11569964/how-to-simulate-a-deadlock-in-sql-server-in-a-single-process)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This script helps simulate deadlocks. Run the entire script in a SQL query window. It will continue running until stopped. | |
In the target script, insert a call to sp_simulatedeadlock where you want the deadlock to occur. | |
This stored procedure, also created below, causes the deadlock. | |
When you are done, stop the execution of this window and run the code in the cleanup section at the bottom. | |
*/ | |
SET NOCOUNT ON | |
IF OBJECT_ID('DeadlockTest') IS NOT NULL | |
DROP TABLE DeadlockTest | |
CREATE TABLE DeadlockTest | |
( | |
Deadlock_Key INT PRIMARY KEY CLUSTERED , | |
Deadlock_Count INT | |
) | |
GO | |
IF EXISTS ( SELECT * | |
FROM sys.sysobjects | |
WHERE id = OBJECT_ID(N'sp_simulatedeadlock') | |
AND OBJECTPROPERTY(id, N'IsProcedure') = 1 | |
) | |
DROP PROCEDURE sp_simulatedeadlock | |
GO | |
CREATE PROCEDURE sp_simulatedeadlock | |
( | |
@MaxDeadlocks INT = -1 -- specify the number of deadlocks you want; -1 = constant deadlocking | |
) | |
AS | |
BEGIN | |
SET NOCOUNT ON | |
IF OBJECT_ID('DeadlockTest') IS NULL | |
RETURN | |
-- Volunteer to be a deadlock victim. | |
SET DEADLOCK_PRIORITY LOW | |
DECLARE @DeadlockCount INT | |
SELECT @DeadlockCount = Deadlock_Count -- this starts at 0 | |
FROM DeadlockTest | |
WHERE Deadlock_Key = 2 | |
-- Trace the start of each deadlock event. | |
-- To listen to the trace event, setup a SQL Server Profiler trace with event class "UserConfigurable:0". | |
-- Note that the user running this proc must have ALTER TRACE permission. | |
-- Also note that there are only 128 characters allowed in the trace text. | |
DECLARE @trace NVARCHAR(128) | |
IF @MaxDeadlocks > 0 | |
AND @DeadlockCount > @MaxDeadlocks | |
BEGIN | |
SET @trace = N'Deadlock Test @MaxDeadlocks: ' | |
+ CAST(@MaxDeadlocks AS NVARCHAR) | |
+ N' @DeadlockCount: ' | |
+ CAST(@DeadlockCount AS NVARCHAR) | |
+ N' Resetting deadlock count. Will not cause deadlock.' | |
EXEC sys.sp_trace_generateevent @eventid = 82 , -- 82 = UserConfigurable:0 through 91 = UserConfigurable:9 | |
@userinfo = @trace | |
-- Reset the number of deadlocks. | |
-- Hopefully if there is an outer transaction, it will complete and persist this change. | |
UPDATE DeadlockTest | |
SET Deadlock_Count = 0 | |
WHERE Deadlock_Key = 2 | |
RETURN | |
END | |
SET @trace = N'Deadlock Test @MaxDeadlocks: ' | |
+ CAST(@MaxDeadlocks AS NVARCHAR) + N' @DeadlockCount: ' | |
+ CAST(@DeadlockCount AS NVARCHAR) | |
+ N' Simulating deadlock.' | |
EXEC sys.sp_trace_generateevent @eventid = 82 , -- 82 = UserConfigurable:0 through 91 = UserConfigurable:9 | |
@userinfo = @trace | |
DECLARE @StartedTransaction BIT | |
SET @StartedTransaction = 0 | |
IF @@trancount = 0 | |
BEGIN | |
SET @StartedTransaction = 1 | |
BEGIN TRANSACTION | |
END | |
-- lock 2nd record | |
UPDATE DeadlockTest | |
SET Deadlock_Count = Deadlock_Count | |
FROM DeadlockTest | |
WHERE Deadlock_Key = 2 | |
-- lock 1st record to cause deadlock | |
UPDATE DeadlockTest | |
SET Deadlock_Count = Deadlock_Count | |
FROM DeadlockTest | |
WHERE Deadlock_Key = 1 | |
IF @StartedTransaction = 1 | |
ROLLBACK | |
END | |
GO | |
INSERT INTO DeadlockTest ( Deadlock_Key , | |
Deadlock_Count | |
) | |
SELECT 1 , | |
0 | |
UNION | |
SELECT 2 , | |
0 | |
-- Force other processes to be the deadlock victim. | |
SET DEADLOCK_PRIORITY HIGH | |
BEGIN TRANSACTION | |
WHILE 1 = 1 | |
BEGIN | |
BEGIN TRY | |
BEGIN TRANSACTION | |
-- lock 1st record | |
UPDATE DeadlockTest | |
SET Deadlock_Count = Deadlock_Count | |
FROM DeadlockTest | |
WHERE Deadlock_Key = 1 | |
WAITFOR DELAY '00:00:10' | |
-- lock 2nd record (which will be locked when the target proc calls sp_simulatedeadlock) | |
UPDATE DeadlockTest | |
SET Deadlock_Count = Deadlock_Count | |
FROM DeadlockTest | |
WHERE Deadlock_Key = 2 | |
ROLLBACK | |
END TRY | |
BEGIN CATCH | |
PRINT 'Error ' + CONVERT(VARCHAR(20), ERROR_NUMBER()) + ': ' | |
+ ERROR_MESSAGE() | |
GOTO cleanup | |
END CATCH | |
END | |
cleanup: | |
IF @@trancount > 0 | |
ROLLBACK | |
DROP PROCEDURE sp_simulatedeadlock | |
DROP TABLE DeadlockTest |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment