🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.delphi.bazy-danych
Article #80964

Re: Logika pewnej transakcji...

#80964
From: ufo
Date: Fri, 11 Dec 2015 18:14
70 lines
3074 bytes
W dniu 2015-12-11 o 10:50, wloochacz pisze:
> W dniu 2015-12-09 o 23:36, ufo pisze:
>> Czy znacie jakieś bardziej "eleganckie" sposoby przeprowadzenia takiej
>> transakcji?. Przychodzi mi jeszcze do głowy Rollback i table1.Insert ale
>> wtedy użytkownik traci dane w formularzu i trzeba by je jakoś przywracać.
> Znacie; CachedUpdates, dopóki user nie naciśnie zapisz, nic nie idzie do
> bazy danych.
> Przy Insert masz to co chciałeś, ale przy Edit musisz "jakoś" zablokować
> dokument przed edycją.
> Pewnie UNIDAC coś tam potrafi zrobić, ale ja używam własnej implmentacji
> z blokowanie całkowicie zarządzanym przez apliakację (wiem kto, kiedy i
> z jakiej maszyny zablokował jaki obiekt biznesowy).
>
>
No, zapis informacji o blokadzie może być przydatny i tez to później
wprowadzę. Oczywiście można korzystać z blokowania przez db lub z
własnego mechanizmu. Można także rozważyć lokalną kopię, gdyby komputer
użytkownika wywalił się w połowie zapisu dużego dokumentu.
Unidac z CachedUpdates blokuje rekord w trybie edycji i ustawionym
trybie blokady Pessimistic. Jeśli anuluje się transakcję wystarczy
uruchomić nową i zablokować ponownie funkcją Lock.
Blokowanie przy użyciu mechanizmów db jest wygodne, może mieć jednak
uboczne skutki, bo niektóre engine, zamiast pojedynczego rekordu,
blokują całą stronę (kilka rekordów).

W każdym razie zamieściłem ostateczną wersję na CachedUpdates. Tu każda
tabela po pomyślnym zapisie, dodaje się do listy. A w razie błędu jest
przywracana do stanu przed zapisem (RestoreUpdates) a całośc zapisu
anulowana przez Rollback.
Troszkę tu moich "overridowanych" funkcji ale powinno być zrozumiałe.

    if (not mdata.db.InTransaction) then mdata.db.StartTransaction;
     Tables:=TList.Create;
     try
       try
         Tables.Capacity:;
         ErrTable:ÚtaQuery;
         if (DataQuery.State in [dsEdit, dsInsert]) then DataQuery.Post;
         if (DataQuery.UpdatesPending) then DataQuery.ApplyUpdates;
         Tables.Add(DataQuery);
         ErrTable:­resFRM.adresQUE;
         adresFRM.Post(EditMode,15,PrimaryKey,'usr_Key','',false); //to
robi post+applyupdates dla tej tabeli
         Tables.Add(adresFRM.adresQUE);
         ErrTable:=telfaxFRM.DataQUE;
         telfaxFRM.ApplyUpdates;
         Tables.Add(telfaxFRM.DataQUE);
         ErrTable:=emailFRM.DataQUE;
         emailFRM.ApplyUpdates;
         Tables.Add(emailFRM.DataQUE);
         ErrTable:=komunikatorFRM.DataQUE;
         komunikatorFRM.ApplyUpdates;
         Tables.Add(komunikatorFRM.DataQUE);
       except on E:Exception do
         begin
           mdata.db.Rollback;
           for i := 0 to Tables.Count-1 do
TUniQuery(Tables[i]).RestoreUpdates;
           if EditMode=dsEdit then
           begin
             mdata.db.StartTransaction;
             DataQuery.Lock;
           end;
           if (E is EUniError) then mdata.DataBaseError(E as
EUniError,Self,ErrTable);
           raise;
         end;
       end;
     finally
       Tables.Free;
     end;

Message-ID: <n4f08p$rub$1@node2.news.atman.pl>
Path: polish.pugleaf.net!archive.newsdeef.eu!apf1.newsdeef.eu!news.usenet.farm!..!..!not-for-mail
References: <n4aad8$c2a$1@node2.news.atman.pl> <566a9c5e$0$22839$65785112@news.neostrada.pl>