Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasy modelu a transakcje
marcini82
post
Post #1





Grupa: Zarejestrowani
Postów: 190
Pomógł: 1
Dołączył: 20.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Witam!

W aplikacji o strukturze wzorowanej na MVC mamy 2 klasy modelu A i B:
1. klasa A posiada metode wykonujaca skomplikowana operacje na bazie danych, skladajaca sie z wielu zapytan, ktore musza byc objete transakcja.
2. metoda klasy B wykonuje cos tam innego w bazie danych
Klasy kontrolerow akcji korzystaja z klas A i B.

Obie klasy i ich metody dotycza niezaleznych elementow serwisu i moga byc wywolywane oddzielnie.
Ale nagle okazuje sie, ze w pewnych przypadkach wykonanie obu operacji jedna po drugiej stanowi logiczna calosc: wykonywana akcja wymaga, aby wywolac metode klasy A, a nastepnie metode klasy B. Pytanie: jak objac pojedyncza transakcja obydwie operacje?

I teraz mamy rozne rozwiazania:
1. Klasa kontrolera akcji wywoluje najpierw metode klasy A a potem klasy B. W tym przypadku transakcja jest objeta tylko pierwsza operacja. Jesli klasa B nie bedzie w stanie wykonac operacji, to stan bazy bedzie nieprawidlowy, bo zmany spowodowane przez klase A nie beda uwzglednione w obszarze kontrolowanym przez klase B. Niefajnie.
2. Klasa kontrolera akcji wywoluje metode klasy A, a ta z kolei korzysta z klasy B. Ale teraz klasa A zaczyna byc zbytnio zalezna od klasy B. A co sie stanie, jesli operacje wewnatrz B rowniez beda objete transakcja? Tez niefajnie...

Macie inne pomysly? Jak zarzadzac transakcjami rozciagnietymi na rozne klasy, z ktorych kazda rowniez moze wymagac zdefiniowania transakcji w swoim wnetrzu?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 4)
DeyV
post
Post #2





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




hmm. Chyba zrobiłbym to w ten sposób.

Kontroler
--
  1. <?php
  2. $ModelA; $ModelB;
  3.  
  4.  
  5. $ModelA->StartTr();
  6. $ModelB->StartTr(); // transakcja może być wystartowana wielokrotnie
  7.  
  8. try{
  9.  
  10.  $ModelA->run();
  11.  $ModelB->run(); // jeśli w A zostanie wywalony wyjątek - B się nawet nie zacznie wykonywać.
  12.  
  13.  
  14.  $ModelA->commit();
  15.  $ModelB->commit(); // w zależności od potrzeb - możemy zamknąć transakcje raz lub dla każdego przypadku osobno (chyba - podobnie jak niżej) 
  16.  
  17. }
  18. catch( Exception $e ){
  19.  $ModelA->RolbackTr();
  20.  $ModelB->RolbackTr(); // rollback może robić coś więcej, niż tylko wycofanie transakcji bazy danych 
  21.  // a zresztą - nawet gdyby robił tylko to, to i tak baza nie powinna (chyba) wyświetlić komunikatu błędu.
  22. }
  23. ?>


W ten sposób przenosimy nieco więcej pracy na kontroler, który musi pamiętać o każdorazowym uruchomieniu obsługi transakcji, ale to nie powinno stanowić problemu.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #3





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Z tym ze powinienes najpierw zcommitowac wewnetrzna tranzakcje, nie?
Go to the top of the page
+Quote Post
DeyV
post
Post #4





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




a dlaczego?

Co to znaczy "wewnętrzna transakcja" ? Większość baz danych pozwala tylko na 1 poziom transakcji, który w całości jest akceptowany / wycofywany.

Więc w takim przypadku commit, gdzie by się nie pojawił, i tak zamknie nam wszystko.

Wywołanie 2 "pseudo commita" dałem tylko po to, by można w nim było zrobić jakieś rzeczy dodatkowe, ewentualnie po to, by zachować porządek w kodzie. (cały mechanizm może przecież być obsługiwany przez autmoat. )
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Teraz juz rozumiem
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.12.2025 - 21:53