Jak zarządzać 2 metodami DAO w jednej transakcji?

12

W wywiadzie ktoś zapytał mnie: jak zarządzamy 2 metodami transakcyjnymi / dao w jednej transakcji. Pożądane możliwości:

  1. Jeśli któryś z nich zawiedzie, musimy wycofać obie metody.
  2. Obie metody można nazwać osobno dołączonymi do pojedynczej transakcji.
  3. Zarządzanie powinno odbywać się na warstwie DAO, a nie na warstwie usługowej.

Myślę: pytanie dotyczy zarządzania wiosennymi transakcjami.

Satish Pandey
źródło

Odpowiedzi:

12

Po pierwsze, zarządzanie transakcjami powinno odbywać się na warstwie usługi, a nie na warstwie DAO, ponieważ spowodowałoby to znaczne obciążenie wydajności (w celu radzenia sobie z odpowiednim poziomem izolacji transakcji i propagacją dla każdej innej metody). Ponadto zakres jednostki pracy pochodzi z warstwy usług zamiast z warstwy dostępu do danych: wyobraź sobie wykonanie procesu biznesowego, który musi poradzić sobie z 2 lub więcej DAO.

W Internecie jest wiele dyskusji na ten temat, tak jak tutaj , tutaj i tutaj .

W każdym razie, ponieważ jest to wywiad, przyjmijmy takie pytanie, jakie jest. Z mojego punktu widzenia używałbyś @Transactionaladnotacji (lub konfiguracji XML) w obu metodach i przy propagacji transakcji z REQUIREDwartością. W ten sposób, po wywołaniu którejkolwiek z tych metod i jeśli nie istnieje żadna poprzednia transakcja, zostanie utworzona nowa transakcja:

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}
Alonso Dominguez
źródło
Czy oznacza to foo()i bar()dzieli tę samą transakcję, a jeśli jedna zawiedzie, kolejna 1 również zostanie wycofana? Czy możesz podać jakieś wyjaśnienie?
Satish Pandey,
cóż, każda metoda deklaruje własną jednostkę pracy: tx zostanie zatwierdzone na końcu każdej metody i jeśli którakolwiek z nich zgłosi wyjątek, zostanie wycofana.
Alonso Dominguez,
więc musimy dodać @Transactional(propagation = REQUIRED)metodę warstwy DAO do propagacji i @Transactionalwarstwy usługi, ale jeśli nałożę @Transactionalwarstwę usługi tylko zamiast warstwy DAO, jaka jest różnica?
atish shimpi
propagation = REQUIREDjest wartością domyślną dla propagacji adnotacji transakcyjnej, więc jej zapisanie nie jest konieczne.
Daniel Higueras,
2

Ignorując wiosnę i frameworki w mojej odpowiedzi ..... podstawowa idea używania parametrów funkcji. Jestem pewien, że koncepcja mogłaby mieć zastosowanie w [wstaw tutaj strukturę].

Będziesz musiał obsługiwać zatwierdzenie / wycofanie poza 2 metodami DAO. Dwie metody musiałyby przyjąć transakcję / połączenie jako dane wejściowe.

kod psuedo:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}
mike30
źródło
1 pytanie: dlaczego podajemy Tran tjako parametr w obu metodach. Czy możesz podać jakieś wyjaśnienie?
Satish Pandey,
@Satish, ponieważ w pytaniu (punkt 1 i 2) metody DAO muszą mieć elastyczność, aby można je było wywoływać niezależnie, a także zależnie. Jeśli dokonujesz transakcji wewnątrz metody 1 za pomocą transakcji o zasięgu lokalnym, nie możesz wycofać, jeśli coś poszło nie tak w metodzie 2, ponieważ już dokonałeś metody 1 przed wywołaniem metody 2.
mike30
0

Istnieje szansa, że ​​dwie metody powinny działać niezależnie także w tym samym czasie, gdy może działać w tej samej transakcji, więc musimy użyć opcji Propagacji. Jeśli transakcja musi przebiegać w tej samej transakcji, użyje pierwszej transakcji, w przeciwnym razie zostanie utworzona nowa transakcja, jeśli zostanie wywołana niezależnie. Popraw mnie, jeśli się mylę.

M. Anil Kumar
źródło
Czy możesz podać przykład?
Jay Elston,