Как управлять двумя методами DAO в одной транзакции?

12

В одном из интервью кто-то спросил меня: как мы управляем 2 транзакционными / дао методами в одной транзакции. Желаемые возможности:

  1. Если кто-то из них потерпит неудачу, нам нужно откатить оба метода.
  2. Оба метода могут быть вызваны отдельно с одной транзакцией.
  3. Управление должно быть на уровне DAO, а не на уровне обслуживания.

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

Сатиш Пандей
источник

Ответы:

12

Прежде всего, управление транзакциями должно осуществляться на уровне обслуживания, а не на уровне DAO, так как это приведет к значительному снижению производительности (для решения проблемы с соответствующим уровнем изоляции транзакций и распространением в каждом отдельном методе). Кроме того, объем единицы работы зависит от уровня обслуживания, а не от уровня доступа к данным: представьте себе выполнение бизнес-процесса, который должен работать с двумя или более DAO.

Существует много дискуссий в Интернете , что точки в этом направлении , как здесь , здесь и здесь .

В любом случае, поскольку это интервью, давайте примем вопрос как есть. С моей точки зрения, вы будете использовать @Transactionalаннотацию (или конфигурацию XML) в обоих методах и с распространением транзакции со REQUIREDзначением. Таким образом, когда любой из этих методов вызывается и если предыдущая транзакция не существует, будет создана новая транзакция:

@Transactional
class MyDAO {

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

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

}
Алонсо Домингес
источник
Значит ли это foo()и bar()делить одну и ту же транзакцию, и если 1 не удастся, другой 1 также откатится? Можете ли вы дать некоторые разъяснения?
Сатиш Пандей
хорошо, каждый метод объявляет свою собственную единицу работы: tx будет зафиксирован в конце каждого метода, и если любой из них выдает исключение, он будет откатан.
Алонсо Домингес
поэтому нам нужно добавить @Transactional(propagation = REQUIRED)метод уровня DAO для распространения и @Transactionalна уровень обслуживания, но если я добавлю @Transactionalтолько уровень обслуживания вместо того, чтобы добавлять на уровень DAO, в чем разница?
Атиш Шимпи
propagation = REQUIREDявляется значением по умолчанию для распространения транзакционной аннотации, поэтому его не обязательно записывать.
Даниэль Игуерас
2

Игнорирование Spring и Framework в моем ответе ..... просто основная идея использования параметров функции. Я уверен, что концепция может применяться в рамках [вставить рамки здесь].

Вам нужно будет обработать коммит / откат вне 2 методов DAO. 2 метода должны были бы принять транзакцию / соединение в качестве входных данных.

код псевдо:

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
источник
1 вопрос: почему мы передаем Tran tв качестве параметра оба метода. Можете ли вы дать некоторые объяснения?
Сатиш Пандей
@Satish, потому что в вопросе (пункты № 1 и № 2) методы DAO должны иметь гибкость, чтобы вызываться как независимо, так и зависимо. Если вы фиксируете внутри method1 с локальной транзакцией, вы не сможете откатиться, если что-то пошло не так в method2, так как вы уже зафиксировали method1 до того, как method2 был вызван.
mike30
0

Существует вероятность того, что два метода должны работать независимо друг от друга, и в то же время они могут выполняться в одной и той же транзакции. Поэтому нам нужно использовать Propagation-Required. Если транзакция должна выполняться в той же транзакции, то она будет использовать первую транзакцию, иначе будет создана новая транзакция, если она будет вызвана независимо. Поправь меня, если я ошибаюсь.

М Анил Кумар
источник
Можете ли вы привести пример, пожалуйста?
Джей Элстон