Guybrush Threepwood Geschrieben 31. März 2014 Teilen Geschrieben 31. März 2014 Ich hab hier ein sehr merkwürdiges Problem. Ich habe ein Programm das mit einem SqlDataReader in einer Schleife über eine Tabelle in einer MSSQL Server 2008 Tabelle läuft und die Datensätze aktualisiert. Damit ich in die Tabelle schreiben kann während der DataReader da drüber läuft hab ich im ConnectionString MultipleActiveResultSets=TRUE [/PHP] hinzugefügt. Bisher hat das auch bei allen Datenbanken mit der es getestet wurde funktioniert, aber jetzt habe ich eine bei der bei jedem Update Command, also beim Aufruf von updateCmd.ExecuteNonQuery();, ein Timeout auftritt. Das Problem lässt sich nicht dadurch beheben das man den Timeout höher stellt da er dann trotzdem auftritt und es handelt sich auch nur um ein einfaches Update Statement das 2 Werte in einem einzigen Datensatz aktualisiert. Merkwürdig ist auch das ich wenn ich im Debugger innerhalb der der DataReader Schleife anhalte auch im SQL Management Studio das Update Commando nicht ausführen kann, sondern da lädt er dann einfach ewig (anscheinend steht der Timeout auf unendlich). Bei den anderen Datenbanken wo der Fehler nicht auftritt kann ich ohne Probleme im Management Studio das Update ausführen während der Debugger in der Schleife steht. Es kann auch nicht daran liegen das die Datenbank irgendwie kaputt wäre da sie vorher jedesmal neu erzeugt und die Daten mit einem anderen Programm aus einer Access DB übernommen werden. An den Daten selber sehe ich auch nichts was das erklären könnte. Ich hab auch schon probiert das Update einfach über eine 2. Connection laufen zu lassen statt über die selbe wo der Reader aktiv ist, aber da tritt auch der Timeout auf (ist ja auch logisch da er im Management Studio auch kommt). Alles in allem bin ich ziemlich ratlos :confused: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Jimbo0915 Geschrieben 31. März 2014 Teilen Geschrieben 31. März 2014 Hi LeChuck Um ehrlich zu sein, habe ich das Konzept gar nicht richtig erfassen können. Ein Datareader lädt den Datensatz raus, du aktualisierst diesen und gibt's dann eine Update Command zurück. ? Was tut der DataReader nachdem er einen Datensatz ausgelesen hat? tritt das Problem auch auf, wenn du dir ne DataTable rauslädst und diese durch iterierst? LG Jimbo Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 31. März 2014 Teilen Geschrieben 31. März 2014 hey, könntest du mal ein bißchen code posten? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 1. April 2014 Autor Teilen Geschrieben 1. April 2014 Ich hab das essentielle mal in ein neus Programm kopiert um zu schauen ob der Fehler da auch auftritt static void Main(string[] args) { int i = 0; using (SqlConnection conn = new SqlConnection(@"Server=.\MyServer;Database=MyDB;Integrated Security=TRUE;MultipleActiveResultSets=TRUE")) { conn.Open(); string tableName = "[MyTable]"; StringBuilder sql = new StringBuilder("SELECT * "); sql.AppendFormat("FROM {0} ORDER BY Field1, Field2, Field3, Field4", tableName); SqlCommand documentCmd = new SqlCommand(sql.ToString(), conn); using (SqlDataReader reader = documentCmd.ExecuteReader()) { while (reader.Read()) { string updateSql = @"UPDATE ExtendedDocumentInformation SET Field5 = @Field5, Field6 = @Field6 WHERE ArchiveGroupID = @ArchiveGroupID AND Field1 = @Field1 AND Field2 = @Field2 AND Field3 = @Field3"; SqlCommand updateCmd = new SqlCommand(updateSql, conn); updateCmd.Parameters.AddWithValue("ArchiveGroupID", reader["ArchiveGroupID"]); updateCmd.Parameters.AddWithValue("Field1", reader["Field1"]); updateCmd.Parameters.AddWithValue("Field2", reader["Field2"]); updateCmd.Parameters.AddWithValue("Field3", reader["Field3"]); updateCmd.Parameters.AddWithValue("Field5", 0); updateCmd.Parameters.AddWithValue("Field6", 2); try { updateCmd.ExecuteNonQuery(); Console.WriteLine("{0}", ++i); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } Console.ReadKey(); } [/PHP] Hier bekomme ich jetzt beim ExecuteNonQuery Aufruf die Folgende Meldung Die Transaktion (Prozess-ID 55) befand sich auf Sperre | generisches Objekt mit Wartemöglichkeit Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus. Scheinbar wird die in meinem anderen Programm irgrndwie verdeckt, aber verstehen tue ich es trotzdem nicht. Vorallem weil das auch hier wieder nur mit der einen DB passiert. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
RipperFox Geschrieben 1. April 2014 Teilen Geschrieben 1. April 2014 Geraten: Deadlocksituation -> Ist vllt. ein Trigger auf ExtendedDocumentInformation, welcher an [MyTable] rumschraubt? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 1. April 2014 Autor Teilen Geschrieben 1. April 2014 Oh da hab ich vergessen den Tabellennamen abzuändern Das Update Statement wird auch auf MyTable ausgeführt. Also wie oben beschrieben passiert das lesen und schreiben auf der selben Tabelle. Trigger oder ähnliches gibt es auch nicht, nur einen zusammengesetzten Primärschlüssel Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 1. April 2014 Autor Teilen Geschrieben 1. April 2014 Hmm wenn ich das SELECT Statment mit WITH(NOLOCK) erweitere funktioniert es in beiden Anwendungen. Ich verstehe allerdings nicht warum er da überhaupt irgendwas lockt und auch nur in der einen DB Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 2. April 2014 Autor Teilen Geschrieben 2. April 2014 Ein Kollege hatte gerade noch ein bessere Lösungsidee und zwar funktioniert es plötzlich auch wenn ich statt ein SELECT * ein SELECT mit den genauen Feldnamen mache. Ich verstehs zwar immer noch nicht aber wenigstens kann ich dann den dirty hack mit dem nolock wieder weg machen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
RipperFox Geschrieben 2. April 2014 Teilen Geschrieben 2. April 2014 Vllt. ist der SELECT (shared lock) mit dem expliziten Lock des UPDATE auf die Spalte in der selben Transaktion kollidiert. Man vergisst recht oft, das SELECTs auch sperren - siehe z.B. tsql - Understanding SQL Server LOCKS on SELECT queries - Stack Overflow Deadlocks kann man mit dem SQL Server Profiler (sogar beim Express dabei) wie hier beschrieben recht gut aufspüren: Save Deadlock Graphs (SQL Server Profiler) Interessant wäre auch die Frage, ob man sich das Einlesen via SQLDataReader nicht überhaupt sparen und die Arbeit in die DB verlagern könnte. Obiger Beispielcode müsste ja z.B. gar nicht lokal laufen - das kann in Deiner Applikation aber ganz anders aussehen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 2. April 2014 Autor Teilen Geschrieben 2. April 2014 (bearbeitet) Danke für die beiden Links, den Deadlockgraphen hatte ich mir auch schon angeschaut, das hat mir aber nicht geholfen zu verstehen warum das aufgetreten ist. Das größte Verständnisproblem was ich dabei noch habe ist warum das mit nem dutzend Datenbanken geklappt hat aber nur bei der einen das Problem aufgetreten ist. und ja in der Anwendung passiert da noch mehr anhand dessen die Werte mitwelchen die Spalten geupdatet werden ermittelt werden, aber das war für das Problem unerheblich Bearbeitet 2. April 2014 von Guybrush Threepwood Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.