Hallo zusammen
Ich habe eine DB, auf welche mit ActiveServerPages zugegriffen wird. Das ganze funktioniert soweit ganz gut.
Wenn aber an einer bestimmten Stelle zwei oder mehrere Personen gleichzeitig zugreifen, entsteht die folgende Fehlermeldung:
Microsoft OLE DB Provider for ODBC Drivers-Fehler '80004005'
[Microsoft][ODBC SQL Server Driver][SQL Server]Your transaction (process ID #8) was deadlocked with another process and has been chosen as the deadlock victim. Rerun your transaction.
/ticketing/reserve.asp, Zeile 37
Kann mir jemand sagen, wie ich diese Meldung umgehen kann bzw. den Server dazu bringe, die Anfragen der Reihe nach auszuführen.
Danke und Gruss
Martin
Wenn aber an einer bestimmten Stelle zwei oder mehrere
Personen gleichzeitig zugreifen, entsteht die folgende
Fehlermeldung:
Überprüf mal auf Deadlocks, die Fehlermeldung ist ja recht eindeutig.
Eine kurzer Erklärung für Deadlock: Stell dir zwei Ressourcen a und b vor und zwei Prozesse P1 und P2. Beide benötigen beide Ressourcen um ihre Aufgabe zu absolvieren.
P1 nimmt sich jetzt a und P2 nimmt sich b. Daraufhin wartet P1 darauf, dass P2 b freigibt, P2 wartet aber darauf, dass P1 a freigibt. Keiner kann weiterarbeiten und *trara* wir haben einen Deadlock.
Das kann bei Datenbanken leicht innerhalb eines Prozesses passieren wenn du zwei verschiedene Transaktionen laufen hast und in beiden auf eine Tabelle zugreifst. Andere Variante wäre aus mehreren Prozessen auf mehrere Tabellen. Gibt natürlich tausend Möglichkeiten, je nachdem wie gelockt wird (Tabelle/Datensatz) usw., überprüf halt mal dein Programm. 
Grüße, Robert
Hallo Robert
Ich habe mir anhand der Fehlermeldung schon gedacht, dass es sich um einen Deadlock handelt 
Leider weiss ich aber nicht wie er zustande kommt. Wenn z.B. zwei User gleichzeitig die folgende Anweisung aufrufen passiert es:
UPDATE Books SET BookingStatus=1, Agent =@AgentID WHERE (BookID=(SELECT MIN(BookID) FROM Books WHERE (Booktype =@BookType AND AgentID is Null AND BookingStatus =0)))
Die Anweisung soll einfach den ersten Titel (Buch) mit dem BookingStatus=1 versehen, der auf die WHERE-Klausel zutrifft.
Danke und Gruss
Martin
Hallo Martin!
Leider weiss ich aber nicht wie er zustande kommt. Wenn z.B.
zwei User gleichzeitig die folgende Anweisung aufrufen
passiert es:
Da müßte man jetzt die Locking-Mechanismen vom SQL-Server besser kennen, hab da leider keine Ahnung wann der da wie was lockt, aber für mich schaut es so aus, als ob das Sub-Select verantwortlich wäre. Probiers mal über zwei getrennte Statements (und schau dir über Debug-Ausgaben an wo wer hängen bleibt).
Grüße, Robert
Hallo Robert
Da müßte man jetzt die Locking-Mechanismen vom SQL-Server
besser kennen, hab da leider keine Ahnung wann der da wie was
lockt, aber für mich schaut es so aus, als ob das Sub-Select
verantwortlich wäre. Probiers mal über zwei getrennte
Statements (und schau dir über Debug-Ausgaben an wo wer hängen
bleibt).
Der Select wird ja in einer Stored-Procedure innerhalb einer Schleife mehrmals aufgerufen. Nun habe ich rausgefunden, dass das Problem nur auftaucht, wenn ich das ganze durch eine Transaktion absichere.
Wenn ich die Transaktion weglasse, dann läuft es prima.
Eine Lösung ist das natürlich nicht.
Gruss
Martin
Grüße, Robert
Hallo Martin!
Der Select wird ja in einer Stored-Procedure innerhalb einer
Schleife mehrmals aufgerufen. Nun habe ich rausgefunden, dass
das Problem nur auftaucht, wenn ich das ganze durch eine
Transaktion absichere.
Hmmmm, dann ist es IMHO relativ klar.
Das erste UPDATE in der Schleife sperrt Datensätze bis zum commit, daraufhin blockt das Sub-SELECT wenn du das zweite Mal den Befehl ausführst, weil er ja nicht zugreifen kann
Du könntest die kleines BookId vorher auslesen und in eine Variable speichern und dann die verwenden. Ist auch schneller weil du dann das SELECT nur einmal ausführen brauchst.
Grüße, Robert
Hallo Robert
Du könntest die kleines BookId vorher auslesen und in eine
Variable speichern und dann die verwenden. Ist auch schneller
weil du dann das SELECT nur einmal ausführen brauchst.
Dann habe ich aber das Problem, dass mir in der Zwischenzeit ein anderer User die entsprechende ID wegnimmt.
Gruss
Martin
PS: Hab’s jetzt mal ohne Transaktion gemacht und frage am Schluss ab, ob die gewünschte Anzahl auch reserviert werden konnte.
Hallo Martin!
Dann habe ich aber das Problem, dass mir in der Zwischenzeit
ein anderer User die entsprechende ID wegnimmt.
Wieso, du liest die ID ja nur aus und schreibst nicht rein. Weiß nicht wirklich was du machen möchtest, aber solange keiner zwischendurch einen kleinere ID reinschreibt (wie wird die ID generiert?) muß es egal sein.
Holzhammer-Methode wäre es vor dem SELECT die ganze Table zu locken und erst wieder freizugeben wenn das letzte Update fertig und die Transaktion committed ist. Ist zwar nicht gut für die Performance, aber dann pfuscht dir sicher keiner rein. 
Grüße, Robert
Hallo Robert
Wieso, du liest die ID ja nur aus und schreibst nicht rein.
Weiß nicht wirklich was du machen möchtest, aber solange
Doch, ich schreibe rein. Das ist eine Tabelle mit x tausend Büchern. Dabei gibt es hunderte gleiche Bücher. Verschiedene User greifen nun rein und nehmen einige der gleichen Bücher. Dabei ist es egal, welche innerhalb des gleichen Typs.
Jeder der Bücher nimmt, markiert diese mit seiner ID (Update), damit sie für die anderen nicht mehr verfügbar sind.
Holzhammer-Methode wäre es vor dem SELECT die ganze Table zu
locken und erst wieder freizugeben wenn das letzte Update
fertig und die Transaktion committed ist. Ist zwar nicht gut
für die Performance, aber dann pfuscht dir sicher keiner rein.
-)
Das wäre natürlich auch eine Methode. Wie kann ich denn eine ganze Tabelle locken?
Gruss
Martin
Das wäre natürlich auch eine Methode. Wie kann ich denn eine
ganze Tabelle locken?
Schau mal auf
http://www.njnet.edu.cn/info/ebook/database/TyMsSQLS…
da ist es genau erklärt.
Falls zu Faul zum Lesen:
SELECT * FROM tabelle (TABLOCKX)
für exklusives locken der ganzen Tabelle (kannst du in deinem SELECT am Anfang unterbringen).
Würde mir das unter dem URL aber auf jeden Fall durchlesen, zumindest teilweise, ist sicher interessant für dich.
Grüße, Robert