123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- CREATE PROCEDURE pr_Deadlock_Test
- /******************************************************************************
- ** File:
- ** Name: pr_Deadlock_Test
- ** Desc: Open two query windows and run this procedure in both windows at the
- ** same time to cause a deadlock.
- ******************************************************************************
- */
- AS
- BEGIN
- SET NOCOUNT ON
- DECLARE @ErrorMessage NVARCHAR(4000);
- DECLARE @ErrorSeverity INT;
- DECLARE @ErrorState INT;
- DECLARE @ErrorNumber INT;
- DECLARE @ErrorLine INT;
- DECLARE @CreatedTables BIT = 0;
- DECLARE @TranCount INT = 0;
- -- These are the tables that will be deadlocking.
- IF OBJECT_ID('dbo.DeadLock1','U') IS NULL
- BEGIN
- CREATE TABLE dbo.Deadlock1
- (
- DeadLockID INT IDENTITY(1,1),
- Deadlock VARCHAR(50),
- PRIMARY KEY(DeadLockID)
- );
- SET @CreatedTables = 1;
- END;
- IF OBJECT_ID('dbo.Deadlock2','U') IS NULL
- BEGIN
- CREATE TABLE dbo.Deadlock2
- (
- DeadLockID INT IDENTITY(1,1),
- Deadlock VARCHAR(50),
- PRIMARY KEY(DeadLockID)
- );
- SET @CreatedTables = 1;
- END;
-
- BEGIN TRY
- IF @CreatedTables = 0
- BEGIN
- -- The tables already exist. Cause a deadlock.
- BEGIN TRAN T2
- SET @TranCount = @TranCount + 1;
- -- A deadlock happens because Deadlock2 is updated before Deadlock1.
- UPDATE dbo.Deadlock2 SET Deadlock = 'Row 3';
- UPDATE dbo.Deadlock1 SET Deadlock = 'Row 3';
- SET @TranCount = @TranCount - 1;
- COMMIT TRAN T2
- END ELSE
- BEGIN
- -- This is the first time this procedure has been run
- -- because the tables needed to be created.
- INSERT INTO dbo.Deadlock1(Deadlock) VALUES('Row 1');
- INSERT INTO dbo.Deadlock2(Deadlock) VALUES('Row 1');
- BEGIN TRAN T1
- SET @TranCount = @TranCount + 1;
- UPDATE dbo.Deadlock1 SET Deadlock = 'Row 2';
- WAITFOR DELAY '00:01:00'; -- Wait for 1 minute. This gives time for the other sql window to run this procedure.
- UPDATE dbo.Deadlock2 SET Deadlock = 'Row 2';
- SET @TranCount = @TranCount - 1;
- COMMIT TRAN T1
- END;
- END TRY
- BEGIN CATCH
- SET @ErrorNumber = ERROR_NUMBER();
- SET @ErrorLine = ERROR_LINE();
- SET @ErrorMessage = 'Error ' + CONVERT(VARCHAR,@ErrorNumber) + ':' + ERROR_MESSAGE() + ' on line ' + CONVERT(VARCHAR,@ErrorLine);
- SET @ErrorSeverity = ERROR_SEVERITY();
- SET @ErrorState = ERROR_STATE();
- -- Try to rollback the transaction.
- IF @TranCount > 0
- BEGIN
- IF @CreatedTables = 0
- BEGIN
- ROLLBACK TRAN T2;
- END ELSE
- BEGIN
- ROLLBACK TRAN T1;
- END;
- END;
- -- Try to delete the tables.
- IF OBJECT_ID('dbo.DeadLock1','U') IS NOT NULL
- BEGIN
- DROP TABLE dbo.Deadlock1;
- END;
- IF OBJECT_ID('dbo.DeadLock2','U') IS NOT NULL
- BEGIN
- DROP TABLE dbo.Deadlock2;
- END;
- RAISERROR(@ErrorMessage,@ErrorSeverity,@ErrorState);
- END CATCH
- -- If successful, try to delete the tables.
- IF OBJECT_ID('dbo.DeadLock1','U') IS NOT NULL
- BEGIN
- DROP TABLE dbo.Deadlock1;
- END;
- IF OBJECT_ID('dbo.DeadLock2','U') IS NOT NULL
- BEGIN
- DROP TABLE dbo.Deadlock2;
- END;
- END
|