У меня есть многоуровневое приложение MVC, использующее JPA 2, Hibernate (без Spring или каких-либо дополнительных фреймворков).
Теперь транзакции выполняются только на уровне DAO, например:
public class AccountDao {
private EntityManagerFactory emf;
public AccountDao(EntityManagerFactory emf) {
this.emf = emf;
}
public void saveAccount(Account account) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(account);
em.getTransaction().commit();
} catch (Exception ex) {
em.getTransaction().rollback();
} finally {
em.close();
}
}
}
Но я хочу получить транзакцию на уровне сервиса:
public class AccountService {
private AccountDao accountDao;
private UserDao userDao;
//needed the method to be in transaction
public void transferUserAccount(){
User user = // ...
userDao.saveUser(user);
Account account = //
accountDao.saveAccount(account);
//rest logic that has to be executed atomically
}
}
Одно из возможных решений - заключить код в метод transferUserAccount()
в другой try/catch/finally
с помощью em.getTransaction().begin()
(или создать собственную аннотацию @Transactional, которая будет это делать под капотом), но я не уверен, как JPA обрабатывает вложенные транзакции.
Также такое решение раскрывает специфические для DAO вещи, такие как менеджер сущностей.
на уровень обслуживания.
В любом случае, подходит ли решение с вложенной транзакцией в transferUserAccount()
?
Есть ли другие решения для таких случаев?
Заранее спасибо!