Transaction was deadlocked on lock resources with another process

0

W aplikacji używam EF i SQL .W serwisie WCF w metodzie której zadaniem jest pobranie czegoś z bazy i edytowanie a następnie zapisanie transakcji, raz na kilkadziesiąt wywołań pojawia się ten błąd:

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

Struktura metody jest taka:


public void method()
{
	using (var context = new dataContext())
	{
		var transaction = context.DatabaseBeginTransaction();
		try
		{
			//bla bla bla

			transaction.Commit();
		
		}
		catch(Exception ex)
		{
			Logger.Error("Error", ex);
			if (transaction != null)
				transacttion.Rollback();
		}
	}
}
 

Za każdym razem jeżeli wywali ten wyjątek i wejdzie w catch wywala kolejny wyjątek na metodzie Rollback (The underlying provider failed on Rollback).

Okazuje się że Rollback mogę się chyba pozbyć bo "DbContextTransaction.Dispose method will be called in the end of the using block"
Tylko ciekawe czemu mi na tym wyjątek leci.

W takim razie to rozwiązanie powinno pomóc?

 

int retryCount = 3;
bool success = false;  
while (retryCount > 0 && !success) 
{
  try
  {
     // your sql here
     success = true; 
  } 
  catch (SqlException exception)
  {
     if (exception.Number != 1205)
     {
       // a sql exception that is not a deadlock 
       throw; 
     }
     // Add delay here if you wish. 
     retryCount--; 
     if (retryCount == 0) throw;
  }
}

lub coś takiego:

 
	dataContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

Macie lepszy pomysł na rozwiązanie tego problemu ?

1

To wygląda tak, jakby dwa wątki wywoływały tą metodę. I raz na ileś tam wywołań się zakleszczają. Spróbuj tą metodę synchronizować. Zwykłym lockiem:

 
object m_lock = new object();

public void method()
{
  lock(m_lock)
  {
    using...//i tu reszta Twojego kodu
  }
}
0

@Juhas Nie wiem czy mogę tą metodę zsynchronizować ponieważ jest to metoda do której teoretycznie "jednocześnie" może być n wywołań. Nie wiem czy przez to się to jakoś nie zablokuje.

1
RideorDie napisał(a):

@Juhas Nie wiem czy mogę tą metodę zsynchronizować ponieważ jest to metoda do której teoretycznie "jednocześnie" może być n wywołań. Nie wiem czy przez to się to jakoś nie zablokuje.

No przecież problem, który opisujesz w tym wątku to właśnie zablokowana baza. :P

Jeśli teoretycznie może być wiele wywołań jakiejś metody robiącej coś na bazie, to właśnie powód, żeby to synchronizować. Zarówno po stronie aplikacji, jak i bazy (poziom izolacji transakcji).

0

@somekind, a jeżeli powyższa metoda to metoda która wykonuje się gdzieś tam w tle niezależnie od działań użytkownika i powiedzmy że jest jeszcze inna metoda i jakimś dziwnym przypadkiem te dwie metody wykonują operacje na bazie na tych samych wierszach jednocześnie i się wzajemnie blokują? Czy to nie jest bardziej prawdopodobne od tego, że metoda na której leci deadlock robi to sama sobie ( dlatego że jeżeli ta metoda będzie wywołana kilka razy jednocześnie to czy naturalnie SQL nie zrobi locka dopóki transakcja się nie skończy? )? Jeżeli powodem deadlocka są dwie różne metody to lock na tej jednej metodzie gdzie wiem, że jest wyjątek tu chyba nic nie pomoże ?

1
RideorDie napisał(a):

@somekind, a jeżeli powyższa metoda to metoda która wykonuje się gdzieś tam w tle niezależnie od działań użytkownika i powiedzmy że jest jeszcze inna metoda i jakimś dziwnym przypadkiem te dwie metody wykonują operacje na bazie na tych samych wierszach jednocześnie i się wzajemnie blokują? Czy to nie jest bardziej prawdopodobne od tego, że metoda na której leci deadlock robi to sama sobie ( dlatego że jeżeli ta metoda będzie wywołana kilka razy jednocześnie to czy naturalnie SQL nie zrobi locka dopóki transakcja się nie skończy? )?

SQL Server nic nie wie o żadnych metodach, on ma tylko transakcje. Nieważne, czy transakcja jest rozpoczęta przez dwie różne metody czy jedną wywoływaną kilkukrotnie.

RideorDie napisał(a):

Jeżeli powodem deadlocka są dwie różne metody to lock na tej jednej metodzie gdzie wiem, że jest wyjątek tu chyba nic nie pomoże ?

No na pewno nie. Musiałbyś zamknąć w sekcji krytycznej cały kod, który robi coś na jednej tabeli.

1 użytkowników online, w tym zalogowanych: 0, gości: 1