2017-08-29 2 views
0

ich eine gespeicherte Prozedur haben, die einige Zeit (~ 60 Sekunden), die ich EF wie mit diesem Aufruf auszuführen nimmt:Aufruf gespeicherte Prozedur von Entity Framework 6 abnormales Verhalten

context.Database.ExecuteSqlCommand(
    "myStoredProcedure @param1", 
    new SqlParameter("param1", param1) 
); 

Die gespeicherte Prozedur besteht aus zwei Teilen :

  1. eine neue Zeile in Tabelle tblSomeTable Einfügen und danach

  2. einige Informationen aus mehreren Tabellen Berechnung, dass nicht enthalten tblSomeTable.

Die zweite Operation ist die zeitaufwendige. Wenn ich diese gespeicherte Prozedur aus SSMS ausführe, kann ich sehen, dass eine neue Zeile zu hinzugefügt wird, bevor die Prozedur beendet, die ein normales Verhalten ist, aber wenn ich die gleiche genaue Prozedur unter Verwendung des obigen Codes dann eine neue Zeile ausführen tblSomeTable wird nur hinzugefügt, wenn der Vorgang abgeschlossen ist.

Auch während das Verfahren läuft, kann ich nicht tblSomeTable überhaupt (beide von EF und SSMS) abfragen, von dem, was ich davon aus, dass es eine Sperre auf tblSomeTable, bis der Vorgang beendet platziert ist. Warum passiert dies?

Dies ist auf SQL Server 2008.

+0

Funktioniert Ihr ExecuteSqlCommand erfolgreich? Sie möchten nur wissen, was Sie während der Ausführung des Befehls in tblSomeTable sehen können? Recht? – CodeNotFound

+0

Ja, tut es, und ja, ich möchte nur die Zeile in der TblSomeTable sehen. (bevor der Vorgang abgeschlossen ist) – astralmaster

Antwort

0

Warum passiert das?

Es ist kein abnormales Verhalten. Sie können die in tblSomeTable eingefügten Daten nicht sehen, da beim Aufruf von context.Database.ExecuteSqlCommand eine neue SQL Server-Transaktion erstellt wird. Dies ist, was die documentation sagt:

Wenn es nicht eine bestehende lokale oder Ambient-Transaktion ist eine neue Transaktion verwendet wird, um den Befehl auszuführen.

Und die Standardisolationsstufe für die Transaktion von EF verwendet wird, ist die höchste, die Serializable ist. Dies bedeutet, dass jede SQL-Abfrage, die außerhalb der Transaktion ausgeführt wird, keine Daten sehen kann, die derzeit in tblSomeTable eingefügt werden, wenn die Transaktion nicht festgeschrieben ist. Die Daten sind für Ihre in SSMS ausgeführte Anfrage unsichtbar, wenn Ihre context.Database.ExecuteSqlCommand ihre Arbeit nicht beendet.

Sie können die Isolationsstufe ändern, aber ich empfehle es nicht, wenn der einzige Zweck darin besteht, zu überprüfen, was Ihre gespeicherte Prozedur beim Aufruf von context.Database.ExecuteSqlCommand tut.

bearbeiten nach @ David Browne - Microsoft Kommentar:

Die Standardisolationsstufe EF ist READ COMMITTED und nicht SERIALIZABLE wie ich oben sagte. Die Unfähigkeit, Daten zu lesen, die nicht festgeschrieben sind, gilt weiterhin.

Definition von documentation:

Gibt an, dass Aussagen keine Daten lesen kann, die geändert wurde, aber nicht von anderen Transaktionen begangen. Dies verhindert schmutzige Lesevorgänge. Daten können durch andere Transaktionen zwischen einzelnen Anweisungen innerhalb der aktuellen Transaktion geändert werden, was zu nicht wiederholbaren Reads oder Phantomdaten führt. Diese Option ist der SQL Server-Standard.

+1

Hinweis EF verwendet standardmäßig keine serialisierbaren Transaktionen. Nur normal Read Committed. –

+0

@ DavidBrowne-Microsoft danke. Meine Antwort wurde aktualisiert. – CodeNotFound

0

Nach dem documentation:

Beginnend mit EF6 Database.ExecuteSqlCommand() standardmäßig den Befehl in einer Transaktion wickeln, wenn man nicht bereits vorhanden war

Sie werden also keine Änderungen in SSMS sehen, bis es endet.

Verwandte Themen