pr_Deadlock_Test.txt 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. CREATE PROCEDURE pr_Deadlock_Test
  2. /******************************************************************************
  3. ** File:
  4. ** Name: pr_Deadlock_Test
  5. ** Desc: Open two query windows and run this procedure in both windows at the
  6. ** same time to cause a deadlock.
  7. ******************************************************************************
  8. */
  9. AS
  10. BEGIN
  11. SET NOCOUNT ON
  12. DECLARE @ErrorMessage NVARCHAR(4000);
  13. DECLARE @ErrorSeverity INT;
  14. DECLARE @ErrorState INT;
  15. DECLARE @ErrorNumber INT;
  16. DECLARE @ErrorLine INT;
  17. DECLARE @CreatedTables BIT = 0;
  18. DECLARE @TranCount INT = 0;
  19. -- These are the tables that will be deadlocking.
  20. IF OBJECT_ID('dbo.DeadLock1','U') IS NULL
  21. BEGIN
  22. CREATE TABLE dbo.Deadlock1
  23. (
  24. DeadLockID INT IDENTITY(1,1),
  25. Deadlock VARCHAR(50),
  26. PRIMARY KEY(DeadLockID)
  27. );
  28. SET @CreatedTables = 1;
  29. END;
  30. IF OBJECT_ID('dbo.Deadlock2','U') IS NULL
  31. BEGIN
  32. CREATE TABLE dbo.Deadlock2
  33. (
  34. DeadLockID INT IDENTITY(1,1),
  35. Deadlock VARCHAR(50),
  36. PRIMARY KEY(DeadLockID)
  37. );
  38. SET @CreatedTables = 1;
  39. END;
  40. BEGIN TRY
  41. IF @CreatedTables = 0
  42. BEGIN
  43. -- The tables already exist. Cause a deadlock.
  44. BEGIN TRAN T2
  45. SET @TranCount = @TranCount + 1;
  46. -- A deadlock happens because Deadlock2 is updated before Deadlock1.
  47. UPDATE dbo.Deadlock2 SET Deadlock = 'Row 3';
  48. UPDATE dbo.Deadlock1 SET Deadlock = 'Row 3';
  49. SET @TranCount = @TranCount - 1;
  50. COMMIT TRAN T2
  51. END ELSE
  52. BEGIN
  53. -- This is the first time this procedure has been run
  54. -- because the tables needed to be created.
  55. INSERT INTO dbo.Deadlock1(Deadlock) VALUES('Row 1');
  56. INSERT INTO dbo.Deadlock2(Deadlock) VALUES('Row 1');
  57. BEGIN TRAN T1
  58. SET @TranCount = @TranCount + 1;
  59. UPDATE dbo.Deadlock1 SET Deadlock = 'Row 2';
  60. WAITFOR DELAY '00:01:00'; -- Wait for 1 minute. This gives time for the other sql window to run this procedure.
  61. UPDATE dbo.Deadlock2 SET Deadlock = 'Row 2';
  62. SET @TranCount = @TranCount - 1;
  63. COMMIT TRAN T1
  64. END;
  65. END TRY
  66. BEGIN CATCH
  67. SET @ErrorNumber = ERROR_NUMBER();
  68. SET @ErrorLine = ERROR_LINE();
  69. SET @ErrorMessage = 'Error ' + CONVERT(VARCHAR,@ErrorNumber) + ':' + ERROR_MESSAGE() + ' on line ' + CONVERT(VARCHAR,@ErrorLine);
  70. SET @ErrorSeverity = ERROR_SEVERITY();
  71. SET @ErrorState = ERROR_STATE();
  72. -- Try to rollback the transaction.
  73. IF @TranCount > 0
  74. BEGIN
  75. IF @CreatedTables = 0
  76. BEGIN
  77. ROLLBACK TRAN T2;
  78. END ELSE
  79. BEGIN
  80. ROLLBACK TRAN T1;
  81. END;
  82. END;
  83. -- Try to delete the tables.
  84. IF OBJECT_ID('dbo.DeadLock1','U') IS NOT NULL
  85. BEGIN
  86. DROP TABLE dbo.Deadlock1;
  87. END;
  88. IF OBJECT_ID('dbo.DeadLock2','U') IS NOT NULL
  89. BEGIN
  90. DROP TABLE dbo.Deadlock2;
  91. END;
  92. RAISERROR(@ErrorMessage,@ErrorSeverity,@ErrorState);
  93. END CATCH
  94. -- If successful, try to delete the tables.
  95. IF OBJECT_ID('dbo.DeadLock1','U') IS NOT NULL
  96. BEGIN
  97. DROP TABLE dbo.Deadlock1;
  98. END;
  99. IF OBJECT_ID('dbo.DeadLock2','U') IS NOT NULL
  100. BEGIN
  101. DROP TABLE dbo.Deadlock2;
  102. END;
  103. END