Spring транзакция с унаследованным кодом с участием двух DAO - PullRequest
0 голосов
/ 03 февраля 2020

Я работаю с устаревшим кодом, где все Spring DAO снабжены аннотацией @Transactional. Теперь у меня есть бизнес-требование, при котором мне нужно вызвать два разных DAO на моем уровне обслуживания и откатить транзакцию, если она в какой-то момент не удалась.

Как мне это сделать весной 5, не удаляя аннотацию @Transactional из DAOs и до сих пор используют их из сервисного уровня. Я не думаю, что приведенный ниже код будет работать, поскольку транзакции в каждом DAO будут независимы друг от друга.

Заранее большое спасибо.

@Transactional
public FooDao {
}

@Transactional
public BarDao {
}


@Transactional
public TestServiceImple implements TestService {
  fooDao.action1();
  barDao.action2();
}

Ответы [ 3 ]

1 голос
/ 03 февраля 2020
  1. Тип распространения по умолчанию для аннотации @Transactional: Propagation.REQUIRED .

Поддержка текущей транзакции, создание новый, если его нет.

По умолчанию откат поведение для аннотации @Transactional выглядит следующим образом

По умолчанию транзакция будет откатываться при RuntimeException и Error, но не при проверке исключения (бизнес-исключения).

Эти две конфигурации по умолчанию гарантируют, что и fooDao.action1(), и barDao.action2() в TestServiceImple будут работать с одним и тем же txn и выполнять откат вместе при любом RuntimeException / пользовательском откате конфигурация на уровне обслуживания, при условии, что эти два метода вызываются из одного и того же метода обслуживания, аннотированного @Transactional.

Пример

 @Transactional
 public TestServiceImple implements TestService {

     public void callDaoMethods(){
      fooDao.action1();
      barDao.action2();
     }

 }

или

public TestServiceImple implements TestService {

 @Transactional
 public void callDaoMethods(){
   fooDao.action1();
   barDao.action2();
 }
}
0 голосов
/ 03 февраля 2020

Если ваша общая цель состоит в том, чтобы гарантировать, что транзакционный откат изменений, сделанных с помощью обоих вызовов dao, при возникновении непроверенного исключения, вы сможете удалить @Transactional из самих методов dao и сохранить его на уровне службы , Транзакционные в Spring могут быть уровня класса или метода, поэтому в этом случае вы можете использовать его только для метода *, который вызывает оба метода dao (хотя, как вы указали, вы, похоже, хотите сохранить эти аннотации в слое dao?) .

Одним из основных моментов транзакций является работа с несколькими изменениями базы данных (множественные вызовы дао), поэтому не очень полезно иметь транзакционную аннотацию для отдельных методов дао (или для слой дао в целом).

Если вы два даоса имеете дело с двумя разными источниками данных (не уверен, вы не упомянули), то, если у вас есть / можно получить данные пружины в качестве зависимости, вы можете использовать ChainedTransactionManager (https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html)

0 голосов
/ 03 февраля 2020

При использовании Propagation.REQUIRED по умолчанию в @Transaction второй метод будет использовать текущую транзакцию. @ Транзакционный (распространение = распространение. ТРЕБУЕТСЯ) , поэтому в итоге это будет только одна транзакция.

...