{"id":270,"date":"2013-02-20T11:26:31","date_gmt":"2013-02-20T11:26:31","guid":{"rendered":"https:\/\/sqlserverlearner.azurewebsites.net\/2013\/02\/20\/deadlock-internals-with-real-time-scenario-explanation-and-resolution\/"},"modified":"2013-02-20T11:26:31","modified_gmt":"2013-02-20T11:26:31","slug":"deadlock-internals-with-real-time-scenario-explanation-and-resolution","status":"publish","type":"post","link":"https:\/\/sqlserverlearner.com\/2013\/02\/20\/deadlock-internals-with-real-time-scenario-explanation-and-resolution\/","title":{"rendered":"Deadlock Internals with Real Time Scenario – Explanation and Resolution"},"content":{"rendered":"
What is deadlock?<\/strong> Scenario:<\/strong> [sql] USE SampleDeadLockDatabase –Create Sample Tables CREATE TABLE SampleTable2(ID INT IDENTITY(1,1),VALUE UNIQUEIDENTIFIER) –Populate Sample tables INSERT INTO SampleTable2(VALUE) –Retreive data for verification Transaction1 Script: (Script-b)<\/em><\/p>\n [sql] UPDATE SampleTable1 —RUN Step2 in Transaction2<\/p>\n –Step3 Begins– ROLLBACK TRAN [\/sql]<\/p>\n Transaction2 Script: (Script-c)<\/em><\/p>\n [sql] UPDATE SampleTable2 –Step4 Begins– ROLLBACK TRAN Data Preparation:<\/strong> Dead Lock Scenario Creation:<\/strong> Analysis:<\/strong> Script-d<\/em> –Update this id with the @@spid of transaction2 –Fetch the partition_id of the table Update the values above with the respective @@spud\u2019s that we noted down earlier. (SPID\u2019s of the respective queries) <\/a><\/p>\n When you execute this you can find that each session has created exclusive lock (X) on the row level and intent exclusive (IX) locks on the page and table level. Script-e:<\/em> This would output the rows that we updated in respective transactions.<\/p>\n <\/a><\/p>\n Now run the step3 in transaction1, and run the script-d pasted above. You will notice that transaction1 now has the new lock for RID 1:156:2 which is in waiting state.
\nA deadlock is a situation in which two or more competing actions are each waiting for the other to finish, and thus neither ever does.
\nRefer: http:\/\/en.wikipedia.org\/wiki\/Deadlock<\/a><\/p>\n
\nData Preparation Script: (Script-a)<\/p>\n
\n–Create Sample Database
\nCREATE DATABASE SampleDeadLockDatabase
\nGO<\/p>\n
\nGO<\/p>\n
\nCREATE TABLE SampleTable1(ID INT IDENTITY(1,1),VALUE UNIQUEIDENTIFIER)
\nGO<\/p>\n
\nGO<\/p>\n
\nINSERT INTO SampleTable1(VALUE)
\nSELECT NEWID()
\nGO 10<\/p>\n
\nSELECT NEWID()
\nGO 10<\/p>\n
\nSELECT * FROM SampleTable1
\nSELECT * FROM SampleTable2
\n[\/sql]<\/p>\n
\nSelect @@SPID — Note down this value here (68)
\n——————Transaction1——————-
\n–Step1 Begins–
\nUSE SampleDeadLockDatabase
\nGO
\nBEGIN TRAN<\/p>\n
\nSET VALUE = ‘1DF1EBE1-322E-4698-A5BD-2E2C6D85AEB6’
\nWHERE ID=1
\n–Step1 Ends–<\/p>\n
\nSELECT * FROM SampleTable2 WHERE ID=4<\/p>\n
\n–Step3 Ends–
\n——————Transaction1——————-<\/p>\n
\nSelect @@SPID — Note down this value here — 65
\n——————Transaction2——————-
\n–Step2 Begins–
\nUSE SampleDeadLockDatabase
\nGO
\nBEGIN TRAN<\/p>\n
\nSET VALUE = ‘23154CCE-0919-4D3A-92EB-E6B4062F8715’
\nWHERE ID=3
\n–Step2 Ends–<\/p>\n
\nSELECT * FROM SampleTable1 WHERE ID=5<\/p>\n
\n–Step4 Ends–
\n——————Transaction2——————-
\n[\/sql]<\/p>\n
\nIn SQL Server Management Studio, Click on new query
\nPaste the Data Preparation Script, and execute it.<\/p>\n
\nPaste the two code snippets transaction1 and transaction 2 in separate query windows.
\nIn each of them highlight the code (SELECT @@SPID) and run it to note down the SPID
\nNow run the Step1 in transaction1
\nThis step updates SampleTable1 with a new value for id 1
\nNow run the Step2 in transaction2
\nThis step updates SampleTable2 with a new value for id 3
\nNow run the Step3 in transaction1
\nThis step selects the values of SampleTable2 with id 4
\nYou will notice that this step3 is still executing. Why? We will analyze this later in the post.<\/em>
\nNow run the Step4 in transaction2
\nThis step selects the values of SampleTable1 with id 5
\nYou will notice that this step executes for few seconds and completes. Also one of the session (Transaction1 or Transaction2 will be deadlocked.) with the errormessage <\/em><\/p>\n
\nMsg 1205, Level 13, State 45, Line 1
\nTransaction (Process ID 65) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
\n<\/font><\/p>\n
\nWhy Step3 was waiting (Blocked?)
\nSo now let us replicate the scenario again, by running the above steps1 and 2.
\nIn the new query window (again a new Query window \ud83d\ude42 ) Run the below script to understand what locks are placed on the tables pages and rows.<\/p>\n
\n[sql]
\n–Update this id with the @@spid of transaction1
\nSELECT resource_type,
\nresource_description,
\nresource_associated_entity_id,
\nrequest_mode,
\nrequest_type,
\nrequest_status FROM sys.dm_tran_locks
\nwhere request_session_id = 68<\/p>\n
\nSELECT resource_type,
\nresource_description,
\nresource_associated_entity_id,
\nrequest_mode,
\nrequest_type,
\nrequest_status FROM sys.dm_tran_locks
\nwhere request_session_id = 65<\/p>\n
\nselect p.partition_id,t.name,t.object_id From sys.partitions p join sys.tables t
\non t.object_id = p.object_id
\nwhere t.name in (‘SampleTable1′,’SampleTable2’)
\n[\/sql]<\/p>\n
\nOutput:<\/em><\/p>\n
\nLet\u2019s find what exactly those rows are.
\nCopy the resource_description values for resource_type RID to the below script and run it.<\/p>\n
\n[sql]
\nselect * From SampleTable1 (nolock) where %%lockres%% = ‘1:154:0’
\nselect * From SampleTable2 (nolock) where %%lockres%% = ‘1:156:2’
\n[\/sql]<\/p>\n
\nOutput:<\/em>
\n<\/a><\/p>\n
\nIt\u2019s waiting for an exclusive lock to be released on a row on SampleTable2
\nIn order to find out the row for which transaction 1 is waiting copy the resource_description values to the below script and run it.
\nScript-f:<\/em>
\n[sql]
\nselect * From SampleTable2 (nolock) where %%lockres%% = ‘1:156:2’
\n[\/sql]<\/p>\n