我有一个使用JPA 2,Hibernate(没有Spring或任何其他框架)的MVC分层应用程序。
现在,仅在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()
中使用嵌套事务的解决方案是否合适?
还有其他解决方案来处理这种情况吗? 预先感谢!
答案 0 :(得分:0)
如果您不想将事务管理泄漏到服务中,我建议进一步拆分DAO,以便DAO具有两个DAO /存储库属性(一个用于User
,一个用于{{1 }}),在DAO方法中创建事务,并将Account
向下传递到EntityManager
-和User
-DAO /存储库。
另一种选择是在Account
中创建方法transferAccount(Account account, user from, user to)
,在此处创建AccountDao
,执行所有逻辑,然后调用transaction
,userDao.save(from, em)
和userDao.save(to, em)
。