Probleme mit Transaktionen mit MS-
SQL-Server 2000 und Delphi und
BDE-
ODBC
Allgemeines :
- Es handelt sich um eine bestehende sehr große Anwendung die bisher unter
Adaptive Server Anywhere 8 läuft und nun zusätzlich auf MS-
SQL-Server 2000 laufen soll.
- Es werden ausschließlich Borland-Delphi-
BDE-Komponenten verwendet.
(TDatabse,TTable,TQuery)
Hier ein Minimal-Beispiel mit dem ich bei mir zu 100% einen Deadlock produzieren kann.
try
Database.StartTransaction;
Query1.SQL.Clear;
Query1.SQL.Add('Update Kunden Set Status = 2 Where ID = 1234');
Query1.ExecSQL;
Query2.SQL.Clear;
Query2.SQL.Add('Select * from Artikel Where ID = 1122'); // Artikel ist eine Tabelle mit 200 Spalten
Query2.Open;
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('Select KundenNr from Kunden Where ID = 1234');
Query1.Open;
// Hier bleibt das Programm bzw. die Datenbank hängen !!!!!!!!!!!!
Database.Commit;
except
Database.Rollback;
end;
Dieses Beispiel ist nur eine extreme Vereinfachung des realen Ablaufes in meinem Programm,
also bitte nicht unnötig über den Sinn nachdenken.
Was der Profiler anzeigt :
SQL:BatchStarting : SET TRANSACTION ISOLATION LEVEL READ COMMITTED auf SPID 51
SQL:BatchStarting : set implicit_transactions on auf SPID 51
SQL:BatchStarting : Update Kunden Set Status = 2 Where ID = 1234 auf SPID 51
SQL:BatchStarting : Select * from Artikel Where ID = 1122 auf SPID 51
. Diverse Lock:Acquired und Lock:Released
.
SQL:BatchStarting : set implicit_transactions on auf SPID 53
SQL:BatchStarting : Select KundenNr from Kunden Where ID = 1234 auf SPID 53
Lock:Acquired: auf SPID53
Lock:Acquired: auf SPID53
Lock:Acquired:auf SPID53
Lock:Acquired:auf SPID53
Lock:TimeOut:auf SPID53
Wenn ich :
- Query2 durch Query1 ersetze, dann funktioniert es.
- Bei der Query2-Abfrage auf eine kleine Tabelle mit 15 Spalten gehe funktioniert es.
Warum kein
ADO ? Umstellungsaufwand ist viel zu groß, auch ASA8 muß weiterhin funktionieren.
Warum keine StoredProcedure ? Transaktion ist viel zu Komplex.
Ich habe gelesen das der
SQL-Server eine neue SPID anlegt, wenn eine Operation zu lange dauert,
aber er kann doch nicht innerhalb einer Transaktion auf einmal eine neue Leitung aufmachen die
nichts von der laufenden Transaktion weiß und diese auch noch blockieren.
Wo ist mein Fehler ????[cl][
dp][/cl][
df][google]