2010-12-11 7 views
1

ich eine Tabelle in SQL Server haben, die etwas wie folgt aussieht:Entity Framework Operations SQL - Prevent Deadlocks

Col1 Id -Int and Key  
Col2 ProductId int  
Col3 ProductDesc Varchar 

In meinem Silverlight-Anwendung, ich habe zwei Gitter Daten aus dieser Tabelle zeigt - getrennt aus der ProductId - Mit anderen Worten, ich habe alle Produkt A's in einem Gitter und alle Produkt B's in dem anderen Gitter.

Wenn ich ein beliebiges Element in einem der beiden Gitter auswähle, schreibe ich es in die Tabelle. Wenn ich einen Gegenstand vom Gitter abnehme, lösche ich die Reihe vom tallle. Da Silverlight Async-Aufrufe verwendet, kann der Benutzer immer noch mit dem anderen Gitter arbeiten (was ich möchte), während ein Gitter beschäftigt ist. Wenn der Benutzer jedoch Elemente aus einem Raster auswählt, während Elemente von dem anderen eingefügt werden, erhalte ich Deadlock-Fehler.

Alle meine Einsätze werden durchgeführt, nachdem jede Entität aktualisiert wurde und ich den Aufruf von SubmitChanges() gemacht habe. Die Löschungen werden anders behandelt. Da in EF kein DeleteAll vorhanden ist, verwende ich den ExecuteStoreCommand() des Objektkontextes und übergebe eine DELETE-Abfrage - wo mein Problem herkommt.

Wie kann ich dieselbe Tabelle verwenden, um Deadlock-Fehler zu vermeiden? Ich versuche wirklich zu vermeiden, einen separaten Tisch für jedes Gitter zu erstellen.

Wenn ich EF verwenden würde, um von meinen Entitäten anstelle von ExecuteStoreCommand() zu löschen, würde EF die Deadlocks besser behandeln? Es scheint wie eine Ressourcen-Taille, um die Tabelle in den Speicher zu laden, die jede Zeile nacheinander löschen.

EDIT: Ich wollte hinzufügen, dass ich überprüft habe, dass meine Deadlocks kommen, wenn ich von der Talbe zur gleichen Zeit lösche EF in es einfügen.

Danke,

-Scott

Antwort

0

Ist Ihre delete-Anweisung die gleichen Zeilen wie die anderen Operationen zu berühren?

Wenn nicht, versuchen Sie einen rowlock Hinweis hinzufügen: Löschen von mit xyz (Dolle), wo ...

+0

Nein, ich bin mir sicher, dass die Zeilen, die gelöscht und eingefügt werden, niemals gleich sein werden. Ich versuche es mal. Das ist eine, die ich noch nie benutzt habe. – Scott

+0

Ich hatte gehofft, dass das den Trick machen würde, aber leider bekomme ich immer noch die Deadlocks. Ich fange an mich zu fragen, ob die Inserts jetzt das Problem sind. Ich habe keine Ahnung, welche Isolationsstufe oder Sperren beim Einsetzen in den Tisch platziert werden. – Scott

+0

Sie könnten versuchen, die Optionen allow_row_locks und allow_page_locks für die Indizes in der Tabelle zu setzen, um Seitensperren zu vermeiden. Bsp: alter index pk_some_table auf some_table rebuild mit (allow_row_locks = on, allow_page_locks = off) – KristoferA

1

Versuchen Isolationsstufen für Ihre Transaktionen mit:

using (TransactionScope scope = 
      new TransactionScope(TransactionScopeOption.RequiresNew, 
      new TransactionOptions() 
      { 
       IsolationLevel = IsolationLevel.ReadUncommitted 
      })) 
{ 
    // read only work - no locks on records. effectively SELECT xx from xxx WITH (NOLOCK) 
} 

jedoch AFAIK ist dies für Scoping EF-Kontextabfragen Wenn Sie ExecuteStoreCommand verwenden, müssen Sie den NOLOCK-Hinweis möglicherweise manuell auf die Abfrage selbst setzen.

+0

Sollte dies für meine löschen oder meine einfügen verwendet werden? Oder beides? – Scott

+0

Weder. Dies sollte für schreibgeschützte Abfragen (SELECT) verwendet werden. Einfügungen und Löschungen * sollten * exklusive Sperren haben. – RPM1984

+0

In SQL Server Management Studio (wenn Sie Zugriff haben) können Sie Abfragen überwachen und feststellen, welche die Deadlocks verursachen. – RPM1984

0

Folgendes funktioniert für mich.

using (var context = new XXX()) // Replace XXX with your specifics 
{ 
    context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"); 
    // your LINQ code here 
}