Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction

I have a C# application which is inserting data into SQL Server (2008) table using stored procedure. I am using multi-threading to do this. The stored procedure is being called from inside the thread. Now my stored procedure is using "tablock" while inserting data. While executing this code I am getting the following error: "Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction."

Can anyone please help me with any solution to this?

like image 739
user1018213 Avatar asked Feb 09 '12 14:02

user1018213


People also ask

How do you resolve deadlock during transaction processing?

The only way to resolve a SQL Server deadlock is to terminate one of the processes and free up the locked resource so the process can complete. This occurs automatically when SQL Server detects a deadlock and kills off one of the competing processes (i.e., the victim).

Was deadlocked on lock resources with another process and has been chosen as the deadlock victim SQL?

“Transaction was deadlocked” error occurs when two or more sessions are waiting to get a lock on a resource which has already locked by another session in the same blocking chain. As a result, none of the sessions can be completed and SQL Server has to intervene to solve this problem.

How do you fix a deadlock error?

Deadlock frequency can sometimes be reduced by ensuring that all applications access their common data in the same order - meaning, for example, that they access (and therefore lock) rows in Table A, followed by Table B, followed by Table C, and so on.

How can stop deadlock in SQL Server?

Useful ways to avoid and minimize SQL Server deadlocksTry to keep transactions short; this will avoid holding locks in a transaction for a long period of time. Access objects in a similar logical manner in multiple transactions. Create a covering index to reduce the possibility of a deadlock.


3 Answers

This occurs when two Sql Server processes are accessing the same resources, but in a different order. Therefore they end up both waiting for the other process, which is a deadlock.

There are a number of ways to prevent it, including:

  • Avoid taking unneccessary locks. Review the transaction isolation level required for the query, use with (nolock) locking hint for queries where appropriate.
  • Make sure that when taking locks you take locks on objects in the same order in each query.

E.g. if Proc1 locks table1 and then table2, but Proc2 locks table2 and then table1, the problem can arise. You can rewrite either proc to take locks in the same order to avoid this problem.

like image 169
Ben Avatar answered Oct 23 '22 11:10

Ben


You can encapsulate your query in a TRY CATCH block, and catching error numbers (related to locks)

  1. 1204
  2. 1205
  3. 1222

Then you can automate retries, up to a certain number.. So you would do something like the following;

         DECLARE @RetryNo Int = 1
     ,@RetryMaxNo Int = 5;
   WHILE @RetryNo < @RetryMaxNo
      BEGIN
         BEGIN TRY 

         -- put your query that generates locks here....

            SELECT   @RetryNo = @RetryMaxNo;
         END TRY
         BEGIN CATCH
            IF ERROR_NUMBER() IN (1204, 1205, 1222)
               BEGIN
                  SET @RetryNo += 1;
                  -- it will wait for 10 seconds to do another attempt
                  WAITFOR DELAY '00:00:10';
               END 
            ELSE
               THROW;
         END CATCH
      END 

You can also use table hints such as UPDLOCK.

like image 33
Mez Avatar answered Oct 23 '22 11:10

Mez


Be sure what field you are going to update or insert, this field have non clustered index. If not availble you can first create nonclustered index of this field on this table and after create follow below steps.

  • Right click on table and select properties.

  • Select Option in right panel in properties.

  • In lock tab Allow page lock make 'False' and Allow row lock must be 'True' and then press Ok.

  • Press New Query button and write command 'update statistics tablename' and execute
  • Rebuild non clustered index.
like image 1
Naveen Avatar answered Oct 23 '22 10:10

Naveen