Avatar billede ellgaard Nybegynder
03. januar 2007 - 12:55 Der er 5 kommentarer og
1 løsning

Try..catch / roll-back el.lign.

Hej

Jeg har en procedure, hvor jeg laver en række af procedurekald

Procedure kald;
object1.set;
object2.set;
object3.set;
...
end;

Hver af disse "set" kommandoer kan gå skidt, hvis objectet er låst, eks. objekt1.locked=true. Hvordan kan jeg sikre, at ingen af kaldene bliver udført, hvis bare én "set" kommando går skidt.

Jeg kunne selvølgelig skrive
if object1.locked=false and object2.locked=false and ... then begin
obejct1.set;
object2.set;
...
end;
men kan det ikke gøres smartere?
Avatar billede a_nor Nybegynder
03. januar 2007 - 15:41 #1
Tror ikke det kan blive meget bedre, måske lige

if not (object1.locked or object2.locked or ...) then

Du skal under alle omstændigheder teste inden du begynder på '...set' ellers skal du igang med noget roll-back som du selv skriver og rekursive procedurer som gør det langt sværere at læse når du engang kommer tilbage koden.


mvh
Anders
Avatar billede hrc Mester
04. januar 2007 - 09:26 #2
Hvis dine objekter fejler med en exception:
begin
  fDone := false;
  if Fejl then
    raise Exception.Create('Objekt x fejlede');

  try
    // arbejde...
    fDone := true;
  finally
  end;
end;

... så kan du lave den sædvanlige try-except tingest med en krølle:

begin
  try
    Object1.Set;
    Object2.Set;
    Object3.Set;   
  except
    on e: exception do
    begin
      if Object1.Done then
        Object1.Rollback;
      if Object2.Done then
        Object2.Rollback;
      if Object3.Done then
        Object3.Rollback;

      MessageDlg('Proceduren fejlede: '#13#10 + e.Message, mtError, [mbOK], 0);
    end;
  end;
end;

Hvis det er database-opdateringer der skal lægges tilbage, så er det letteste at lave en transaktion:

begin
  Database.StartTransaction;
  try
    Object1.Set;
    Object2.Set;
    Object3.Set;

    Database.Commit;
  except
    Database.Rollback;
    raise;
  end;
end;

I dine ObjektX-objekter kan du spørge om der er transaktioner i gang eller om der skal laves nye

var
  LocalTransaction : boolean;
begin
  LocalTransaction := not Database.InTransaction;
  if LocalTransaction then
    Database.StartTransaction;
  try
    // arbejde
    if LocalTransaction then
      Database.Commit;
  except
    if LocalTransaction then
      Database.Rollback;
    raise;
  end;
end;
Avatar billede hrc Mester
04. januar 2007 - 09:29 #3
Du kunne også definere dine egne exceptions:

type
  Object1Exception = class(Exception);
  Object2Exception = class(Exception);
  Object3Exception = class(Exception);

...

  try
  except
    on e: Object2Exception do
      Object1.Rollback;
    on e: Object1Exception do
    begin
      Object2.Rollback;
      Object1.Rollback;
    end;
    on e: Object3Exception do
    begin
      Object3.Rollback;
      Object2.Rollback;
      Object1.Rollback;
    end;
  end;
end;

... men det er ikke meget kønnere end det første oplæg.
Avatar billede ellgaard Nybegynder
18. august 2010 - 15:26 #4
Lukket
Avatar billede hrc Mester
19. august 2010 - 09:01 #5
Var der virkelig ikke noget du kunne bruge her???
Avatar billede ellgaard Nybegynder
25. august 2010 - 22:18 #6
Jeg fik en automatisk mail om, at jeg skulle lukke spørgsmålet, da der ikke havde været aktivitet i lang tid. Der var ikke nogen, der havde lagt et svar, jeg kunne acceptere, og jeg ville ikke til at åbne sagen igen efter 3½ år. Derfor lukkede jeg den bare. Beklager hvis det er brud med god skik. Det var ikke min hensigt.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester