Gleichzeitige Zugriff auf eine Datenbank mit Entity Framework == EntityException

8

Ich habe eine MS SQL 2008-Datenbank, auf die über LINQ für die Datenaktualisierung / -retribution zugegriffen wird.

Auf meine Linq wird von WCF-Diensten in einem PerCall-Instanziierungsmodus für eine schwere Anwendung zugegriffen. Diese Anwendung hat mehrere Threads, die Aufrufe an den Dienst und mehrere Anwendungen gleichzeitig ausgeführt werden.

Ich habe oft eine EntityException passiert:

  

System.Data.EntityException wurde abgefangen     Nachricht = Beim Starten einer Transaktion auf der Provider-Verbindung ist ein Fehler aufgetreten. Weitere Informationen finden Sie in der inneren Ausnahme.     Quelle = System.Data.Entity     StackTrace:          bei System.Data.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevel isolationLevel)          bei System.Data.EntityClient.EntityConnection.BeginTransaction ()          bei System.Data.Objects.ObjectContext.SaveChanges (SaveOptions-Optionen)          bei Infoteam.GfK.TOMServer.DataServer.DataServer.SaveChanges () in D: \ Workspace \ XYZWASDF \ Dataserver \ DataServer.cs: Leitung 123     InnerException: System.Data.SqlClient.SqlException          Nachricht = Une nouvelle transaction n'est pas Autorisée parce que d 'autres threads sont en cours d'exécution dans la session.          Quelle = .Net SqlClient-Datenanbieter          ErrorCode = -2146232060          Klasse = 16          Zeilennummer = 1          Nummer = 3988          Vorgehensweise=""          Server = ift-srv114          Status = 1          StackTrace:               bei System.Data.SqlClient.SqlConnection.OnError (SqlException-Ausnahme, boolean breakConnection)               bei System.Data.SqlClient.SqlInternalConnection.OnError (SqlException Ausnahme, Boolean Breakconnection)               bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning ()               bei System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand CmdHandler, SqlDataReader Datenstrom, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)               bei System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (Byte [] Puffer, TransactionManagerRequestType Anfrage, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 Timeout, SqlInternalTransaction Transaktion, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)               bei System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (Transactiontransaction, String transactionName, Isolation iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)               bei System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction (Transactiontransaction, String name, Isolation iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)               bei System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction (IsolationLevel iso, String transactionName)               bei System.Data.SqlClient.SqlInternalConnection.BeginTransaction (IsolationLevel iso)               bei System.Data.SqlClient.SqlConnection.BeginDbTransaction (IsolationLevel isolationLevel)               bei System.Data.Common.DbConnection.BeginTransaction (IsolationLevel isolationLevel)               bei System.Data.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevel isolationLevel)          InnerException:

(Entschuldigung, es ist nicht gut lesbar). (Die Nachricht der internen Ausnahme bedeutet "Eine neue Transaktion ist nicht zulässig, da andere Threads in der Sitzung ausgeführt werden."

Ich habe überprüft, ich bin nicht in einer Schleife, es ist rein zufällig, wenn es diese Ausnahme macht, und ich habe keine Ahnung, wie man das vermeidet.

jede Hilfe wird wirklich geschätzt werden:)

Danke!

EDIT: Hier ist ein Beispiel, wo ich diese Ausnahme einige Male bekam

%Vor%     
J4N 28.02.2011, 15:00
quelle

1 Antwort

7

Ohne den Code zu sehen, lautet die kurze Antwort, dass EntityFramework nicht Thread-sicher ist. Sie erhalten diesen Fehler in einem scheinbar zufälligen Muster, wenn sich zwei + Threads überschneiden, wenn Sie versuchen, auf Ihre ObjectContext zuzugreifen. Ich nehme an, Sie haben Ihren Kontext in eine static Variable gefüllt. Machen Sie den Kontext zu einer lokalen Variablen oder schreiben Sie den Zugriff auf ObjectContext .

Wenn Sie eine spezifischere Antwort wünschen, hilft das Posten Ihres Codes.

Bearbeiten

Ihr Problem besteht darin, dass zwei Threads versuchen, den Kontext zur gleichen Zeit zu verwenden, oder wenn ein Thread eine Transaktion geöffnet lässt und ein zweiter Thread versucht, Ihren Singleton-Kontext zu verwenden. Ihr Code-Snippet wirft für mich mehr Fragen auf als zuvor.

  • In Ihrem Codebeispiel ist _ lockObject eine statische Variable?
  • Warum zeigen Sie die Sperre in SaveChanges an, erklären dann aber, dass ein Fehler ausgelöst wird von InsertOrUpdateDetachedObject ? Können wir den Code für InsertOrUpdateDetachedObject ?
  • sehen?
  • Verwenden SaveChanges dasselbe _lockObject wie alle anderen Methoden, die direkt auf den Kontext zugreifen?
  • Ist Ihr Aufruf von _context.SaveChanges die einzige Möglichkeit, die Sie in der Datenbank speichern, oder haben Sie andere Bereiche, die Transaktionskontexte selbst öffnen?
  • Sie verwenden einen Singleton, damit Ihr Kontext über mehrere Anrufe hinweg geteilt wird. Es ist möglicherweise vorzuziehen, für jeden WFC-Aufruf einen neuen Kontext zu erstellen.
EBarr 28.02.2011, 15:22
quelle