Georg Hübner
2013-03-02 15:37:45 UTC
Hallo,
ich benutze für mein Programm Interbase als Datenbank und greife über Stored procedures darauf zu.
Das Problem ist, wenn ich den Code in einem Service laufen lasse bekomme ich immer eine "deadlock-Meldung".
Lasse ich den Code in einer normalen Anwendung laufen, gibt es keine Exceptions.
Alles läuft dann so wie es soll, ohne Fehler.
Ich weis leider keinen Rat, wie ich das Ganze als Service fehlerfrei und dauerhaft zum Laufen bekomme. :-(
Hat jemand eine Idee?
Die Datenbankaktion werden über ein Timer-Event gesteuert:
procedure TForm1.Timer1Timer(Sender: TObject);
var
AktDateTime: TMyDateTime;
begin
AktDateTime:=GetAktDateTime;
if Stundenwechsel then
begin
SaveDBStundendaten; //Insert Stundendaten, in dieser Sub-Routine tritt die Exception auf
UpdateDBTagesdaten; //Update Tagesdaten, hier keine Exception
UpdateDBMonatsdaten; //Update Monatsdaten, hier keine Exception
FLastDataDateTime.Stunde:=AktDateTime.Stunde;
end;
// ab hier wird noch getestet. Im der normalen Anwendung gab es keine Probleme
if Tageswechsel then
begin
SaveDBTagesdaten; //Insert Tagesdaten, Delete Stundendaten
FLastDataDateTime.Tag:=AktDateTime.Tag;
end;
if Monatswechsel then
begin
SaveDBMonatdaten; //Insert Monatsdaten
FLastDataDateTime.Monat:=AktDateTime.Monat;
FLastDataDateTime.Jahr:=AktDateTime.Jahr;
end;
end;
Hier die Procedure für DB-Zugriff:
procedure TForm1.SaveDBStundendaten;
begin
try
IBStoredProcInsStd.ExecProc;
IBTransactionInsStd.Commit;
except
on E: Exception do
begin
WriteErrFile(E.Message,' / Unit MainServer: procedure SaveDBStundendaten');
IBTransactionInsStd.Rollback;
end;
end;
end;
Die Exceprion-Meldung:
deadlock update conflicts with concurrent update In Modul: / Unit MainServer: procedure SaveDBStundendaten
Der vollständighalber hier noch die aufgerufene Stored procedures:
/* Stored procedures */
ALTER PROCEDURE "INSERT_STUNDENDATEN"
AS
declare variable Date_D Date;
declare variable Time_T Time;
declare variable JAH INTEGER;
declare variable MON INTEGER;
declare variable TAH INTEGER;
declare variable STU INTEGER;
declare variable S_Int INTEGER;
declare variable C_Int INTEGER;
declare variable E_Int INTEGER;
BEGIN
/* aktuelle Zeit holen */
Date_D = CURRENT_DATE;
Time_T = CURRENT_TIME;
JAH=Extract(year FROM Date_D);
MON=Extract(month FROM Date_D);
TAH=Extract(day FROM Date_D);
STU=Extract(hour FROM Time_T);
/* alle gesammelten Daten holen und Durchschnitt ermitteln */
Select Sum(Inhalt), Count(Inhalt)
From StdInhalt
Into :S_Int, :C_Int;
if (C_Int > 0) then
begin
E_Int = S_INT / C_Int; /* Durchschnitt berechnen */
Delete From StdInhalt; /* alle "gesammelten" Daten löschen */
end
else
begin
Select Inhalt /* wenn keine gesammelten Daten vorhanden, dann aktuellen Wert holen */
From Aktuell
Where LfdNr = 1
Into :E_Int;
end
/* neuen Stundendatensatz anlegen */
Insert Into Stundendaten (jahr, monat, tag, stunde, inhalt)
Values(:"JAH", :"MON", :"TAH", :"STU", :E_Int);
suspend;
END
Mfg
Georg Hübner
ich benutze für mein Programm Interbase als Datenbank und greife über Stored procedures darauf zu.
Das Problem ist, wenn ich den Code in einem Service laufen lasse bekomme ich immer eine "deadlock-Meldung".
Lasse ich den Code in einer normalen Anwendung laufen, gibt es keine Exceptions.
Alles läuft dann so wie es soll, ohne Fehler.
Ich weis leider keinen Rat, wie ich das Ganze als Service fehlerfrei und dauerhaft zum Laufen bekomme. :-(
Hat jemand eine Idee?
Die Datenbankaktion werden über ein Timer-Event gesteuert:
procedure TForm1.Timer1Timer(Sender: TObject);
var
AktDateTime: TMyDateTime;
begin
AktDateTime:=GetAktDateTime;
if Stundenwechsel then
begin
SaveDBStundendaten; //Insert Stundendaten, in dieser Sub-Routine tritt die Exception auf
UpdateDBTagesdaten; //Update Tagesdaten, hier keine Exception
UpdateDBMonatsdaten; //Update Monatsdaten, hier keine Exception
FLastDataDateTime.Stunde:=AktDateTime.Stunde;
end;
// ab hier wird noch getestet. Im der normalen Anwendung gab es keine Probleme
if Tageswechsel then
begin
SaveDBTagesdaten; //Insert Tagesdaten, Delete Stundendaten
FLastDataDateTime.Tag:=AktDateTime.Tag;
end;
if Monatswechsel then
begin
SaveDBMonatdaten; //Insert Monatsdaten
FLastDataDateTime.Monat:=AktDateTime.Monat;
FLastDataDateTime.Jahr:=AktDateTime.Jahr;
end;
end;
Hier die Procedure für DB-Zugriff:
procedure TForm1.SaveDBStundendaten;
begin
try
IBStoredProcInsStd.ExecProc;
IBTransactionInsStd.Commit;
except
on E: Exception do
begin
WriteErrFile(E.Message,' / Unit MainServer: procedure SaveDBStundendaten');
IBTransactionInsStd.Rollback;
end;
end;
end;
Die Exceprion-Meldung:
deadlock update conflicts with concurrent update In Modul: / Unit MainServer: procedure SaveDBStundendaten
Der vollständighalber hier noch die aufgerufene Stored procedures:
/* Stored procedures */
ALTER PROCEDURE "INSERT_STUNDENDATEN"
AS
declare variable Date_D Date;
declare variable Time_T Time;
declare variable JAH INTEGER;
declare variable MON INTEGER;
declare variable TAH INTEGER;
declare variable STU INTEGER;
declare variable S_Int INTEGER;
declare variable C_Int INTEGER;
declare variable E_Int INTEGER;
BEGIN
/* aktuelle Zeit holen */
Date_D = CURRENT_DATE;
Time_T = CURRENT_TIME;
JAH=Extract(year FROM Date_D);
MON=Extract(month FROM Date_D);
TAH=Extract(day FROM Date_D);
STU=Extract(hour FROM Time_T);
/* alle gesammelten Daten holen und Durchschnitt ermitteln */
Select Sum(Inhalt), Count(Inhalt)
From StdInhalt
Into :S_Int, :C_Int;
if (C_Int > 0) then
begin
E_Int = S_INT / C_Int; /* Durchschnitt berechnen */
Delete From StdInhalt; /* alle "gesammelten" Daten löschen */
end
else
begin
Select Inhalt /* wenn keine gesammelten Daten vorhanden, dann aktuellen Wert holen */
From Aktuell
Where LfdNr = 1
Into :E_Int;
end
/* neuen Stundendatensatz anlegen */
Insert Into Stundendaten (jahr, monat, tag, stunde, inhalt)
Values(:"JAH", :"MON", :"TAH", :"STU", :E_Int);
suspend;
END
Mfg
Georg Hübner