2009-06-28 28 views
1

Ich habe ein seltsames Problem in Sql Server festgestellt. Ich habe eine Pocket-PC-Anwendung, die sich mit einem Web-Service verbindet, der sich wiederum mit einer Datenbank verbindet und viele Daten einfügt. Der Webservice öffnet eine Transaktion für jeden Pocket PC, der sich mit ihm verbindet. Jeden Tag um 12 Uhr werden 15 bis 20 Leute mit verschiedenen Pocket-PCs gleichzeitig mit dem Web-Service verbunden und die Übertragung erfolgreich abgeschlossen. Danach bleibt jedoch eine offene Transaktion (im Aktivitätsmonitor sichtbar), die 4000 exklusiven Sperren zugeordnet ist. Nach ein paar Stunden verschwinden sie (wahrscheinlich etwas raus) und einige der übertragenen Daten werden gelöscht. Gibt es eine Möglichkeit, diese Sperren zu verhindern? Oder sie programmatisch erkennen und auf ein Entsperren warten?Transaktions-Commit wird erfolgreich ausgeführt, aber nicht ausgeführt

Vielen Dank.

Antwort

0

Bei vielen Tests habe ich festgestellt, dass ein Deadlock passiert. Aber ich konnte den Grund nicht finden, da ich einfach so viele Datensätze in einige unabhängige Tabellen einfüge. half Diese Links ein wenig, aber ohne Glück:

http://support.microsoft.com/kb/323630

http://support.microsoft.com/kb/162361

ich meine Transaktionen auch auf kleinere brach, aber ich habe immer noch aus der Sackgasse.Ich entfernte schließlich die Transaktionen und änderte den Code, um sie nicht aus der Quelldatenbank zu löschen, und die Deadlocks nicht mehr erhalten.

Als eine Lektion, jetzt weiß ich, wenn Sie einige (mehr als eine) große Transaktionen in der gleichen Datenbank zur gleichen Zeit ausgeführt haben, werden Sie sicher Probleme in SQL Server haben, ich weiß nicht über Oracle .

1

Sie können SQL Server Profiler verwenden, um die auftretenden Anweisungen einschließlich Beginn und Ende von Transaktionen zu überwachen. Es gibt auch einige Tools von Microsoft Support, die großartig sind, da sie Profiler und blockierende Skripte ausführen. Ich schaue, ob ich finde, dass diese aktualisiert werden, wenn ich/tue.

Wenn Sie eine offene Transaktion haben, sollten Sie dies im Aktivitätsmonitor sehen können, damit Sie prüfen können, ob offene Transaktionen vor dem Neustart des Servers vorliegen.

bearbeiten

Es klingt wie dieses Problem jeden Tag ungefähr zur gleichen Zeit passiert. Sie sollten es einschalten, bevor das Problem auftritt.

+0

Danke. Aber Profiler zeigt keine Aktivität an, wenn seine Ablaufverfolgung nach dem Beginn der Transaktion gestartet wird. – reticent

+0

Genau. Ich habe heute Morgen mit der Spur begonnen, und ich stöbere nach etwas Seltsamem oder nach etwas über Schlösser. Weißt du etwas, das ich überprüfen sollte? – reticent

0

Ich vermute, dass Sie etwas falsch im Code tun, haben Sie Befehl Zeitüberschreitungen auf einen ausreichend großen Wert gesetzt, um ihre Arbeit zu erledigen, oder möglicherweise ein Fehler ein COMMIT überspringen?

Sie überprüfen können, welche Transaktionen offen sind, indem Sie:.

DBCC OPENTRAN 
+0

Ich habe die Zeitüberschreitung des Befehls nicht geändert, und ich bin mir sicher, dass das Commit ausgeführt wird (weil ich 3 Transaktionen gleichzeitig festlege, eins in MySql, eins in SqlServer und ein anderes in SqlCE), die anderen beiden Transaktionen sind committed und ich kann siehe die Daten). DBCC OPENTRAN zeigt eine offene Transaktion nach dem Festschreiben. Ich weiß einfach nicht, was ich jetzt tun soll, um es zu tun. – reticent

+0

Können Sie Ihren Code verkleinern, klein genug, dass Sie ihn hier veröffentlichen können? –

+0

// Alle Methoden werden vom Webservice aufgerufen, der von einem Geräteprojekt innerhalb einer SqlCE-Transaktion aufgerufen wird public DataService() { mySqlService = new mySqlService(); Verbindung = neue SqlConnection (connectionString); Verbindung.Öffnen(); Transaktion = Verbindung.BeginTransaction(); } ... // Methoden zur Übertragung von Daten - sie Transaktion verwenden public void Commit() { transaction.commit(); mySqlService.Commit(); Verbindung.schließen(); } public void Rollback() { Transaktion.Rollback(); mySqlService.Rollback(); } – reticent

2

Sie sp_lock laufen konnte und überprüfen, um zu sehen, ob es irgendwelche exklusiven Sperren für Tabellen gehalten sind Sie daran interessiert sind, dass wird Ihnen die SPID der betreffenden Verbindung, und Sie können sp_who oder sp_who2 verwenden, um weitere Informationen zu dieser SPID zu finden.

Alternativ bietet Ihnen der Aktivitätsmonitor in Management Studio grafische Versionen dieser Informationen und ermöglicht es Ihnen, alle problematischen Prozesse zu beenden (der Befehl kill ermöglicht Ihnen, das Gleiche in einem Abfrageeditor zu tun).

+0

Danke. Ich musste warten bis es wieder passiert - jetzt. Wie Active Monitor zeigt, gibt es eine offene Transaktion, die einem Prozess zugeordnet ist. Und mit sp_lock sehe ich ungefähr 7000 Sperren für diese SPID. Ist es abnormal? Wenn ja, wie kann ich das verhindern? Oder gibt es eine Möglichkeit, diese Transaktion zu tätigen? Denn das Töten ist keine Option in Bezug auf mein Problem. Danke nochmal. – reticent

+0

Das ist eine ziemlich hohe Anzahl von Schlössern! Die, nach denen Sie Ausschau halten müssen, sind exklusive Sperren, die als X markiert sind, da sie alle den Zugriff auf die zugrunde liegenden Ressourcen blockieren. (IX, Absichtssperren, verhindern, dass andere Sperren für übergeordnete Objekte erhalten; wenn dieser Prozess eine X-Sperre für eine Zeile hat, sind die Seite und die Tabelle, die diese Zeile enthält, IX-gesperrt). Wie für den gierigen Prozess, schauen Sie sich sp_who2 an, um herauszufinden, wo es sich verbindet und was die Anwendung ist. Das sollte helfen, zu debuggen. Dann können Sie andere Techniken wie SQL Profiler verwenden, um das Debuggen zu optimieren. –

+0

72 von ihnen sind IX und alle anderen sind X. Wie sp_who2 zeigt, kommt es von meinem Web-Service-Benutzer, und es heißt, der Status ist "schlafen". Ich habe meinen Code letzten Mal debugged, und ich bin sicher, dass es keine Ausnahme gibt. Gibt es irgendwelche Informationen, die ich nach jedem Einfügen programmatisch überprüfen kann/sollte? Kann ich die Transaktionen in irgendeiner Weise konfigurieren, um diese Sperren zu vermeiden? – reticent

0

Das Zeitlimit bei der Auswahl zeigt an, dass die Transaktion noch geöffnet ist und mindestens einen Teil der Tabelle gesperrt ist.

Wie machen Sie Transaktionen über Web-Services? Wie/wo in Ihrem Code tätigen Sie die Transaktion?

+0

Ich verwende System.Data.SqlClient. Ich habe einen WebMethod, der von den Pocket PCs aufgerufen wird, der die Transaktion startet, Daten einfügt und festlegt. Die gesamte Methode befindet sich in einem try/catch-Block, der die Transaktion im Falle einer Ausnahme zurücksetzt. Habe ich deine Frage beantwortet? – reticent

+0

Es tut mir leid! Ich habe mich geirrt. Ich benutze MyGeneration.doodads (Ich benutze. Net-Provider für meine SqlCe-Datenbank). doodads hat einen TransactionMgr, der die Transaktionen abwickelt. Ich habe den ganzen Code geändert, um heute den .Net Sql-Provider zu verwenden, um zu sehen, ob sich etwas ändert. – reticent

Verwandte Themen