Як керувати 2 методами DAO за одну транзакцію?


12

В інтерв'ю хтось запитав мене: як ми можемо керувати двома транзакційними / дао методами в одній транзакції. Бажані можливості:

  1. Якщо хтось із них не вдається, нам потрібно відкатати обидва способи.
  2. Обидва способи можна назвати окремо, приєднаними до однієї транзакції.
  3. Управління повинно бути на рівні DAO, а не на рівні обслуговування.

Я думаю: питання стосується весняного управління транзакціями.

Відповіді:


12

Перш за все, управління транзакціями має здійснюватися на рівні обслуговування, а не на шарі DAO, оскільки це створить велику накладну ефективність (для вирішення відповідного рівня ізоляції транзакцій та їх розповсюдження при кожному різному методі). Також обсяг одиниці роботи надходить із сервісного рівня замість рівня доступу до даних: уявіть, що виконувати бізнес-процес, який повинен мати справу з 2 або більше DAO.

В Інтернеті багато дискусій, які вказують у тому напрямку, як тут , тут і тут .

У будь-якому випадку, оскільки це інтерв'ю, давайте приймемо питання таке, яке є. З моєї точки зору, ви б використовували @Transactionalанотацію (або конфігурацію XML) в обох методах та з поширенням транзакції зі REQUIREDзначенням. Таким чином, коли буде застосовано будь-який із цих методів і якщо немає попередньої транзакції, буде створено нову транзакцію:

@Transactional
class MyDAO {

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

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

}

Чи означає це foo()і bar()поділити ту саму транзакцію, і якщо 1 не вдасться, ще 1 також буде відкатати? Чи можете ви дати роз'яснення?
Satish Pandey

добре, кожен метод оголошує свою власну одиницю роботи: tx буде зроблено в кінці кожного методу, і якщо будь-який з них кидає виняток, він буде відкотуватися.
Алонсо Домінгуес

тому нам потрібно додати @Transactional(propagation = REQUIRED)метод шару DAO для розповсюдження та @Transactionalслужбовий рівень, але якщо я розміщую @Transactionalлише сервісний шар замість того, щоб наносити шар DAO, у чому різниця?
atish shimpi

propagation = REQUIREDє типовим значенням для поширення транзакційних анотацій, тому записувати його не потрібно.
Даніель Ігуерас

2

Ігноруючи весну та рамки у моїй відповіді ..... лише основна ідея використання параметрів функції. Я впевнений, що ця концепція може застосовуватися в межах [вставки сюди].

Вам потрібно буде обробити фіксацію / відкат поза двома методами DAO. Дві методи повинні взяти транзакцію / з'єднання як вхідний.

код 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();  }
}

1 питання: чому ми передаємо Tran tяк параметр обидва методи. Ви можете дати пояснення?
Satish Pandey

@Satish, тому що у питанні (пункт №1 та №2) методи DAO повинні мати гнучкість, щоб їх можна було викликати незалежно та залежно. Якщо ви здійснюєте метод method1 всередині транзакції локальної області, то ви не зможете скотитися назад, якщо щось пішло не так у method2, як ви вже здійснили method1 до виклику method2.
mike30

0

Є ймовірність того, що два методи повинні працювати незалежно, і в той же час вони можуть працювати в одній транзакції. Отже, нам потрібно використовувати потрібне розповсюдження. Якщо транзакція повинна виконуватись в одній транзакції, тоді вона використовуватиме першу транзакцію, якщо нова операція буде створена, якщо викликати її незалежно. Виправте мене, якщо я помиляюся.


Чи можете ви надати приклад, будь ласка?
Джей Елстон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.