JPA服务层事务

时间:2019-06-30 14:54:14

标签: java hibernate jpa entitymanager

我有一个使用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()中使用嵌套事务的解决方案是否合适?

还有其他解决方案来处理这种情况吗? 预先感谢!

1 个答案:

答案 0 :(得分:0)

如果您不想将事务管理泄漏到服务中,我建议进一步拆分DAO,以便DAO具有两个DAO /存储库属性(一个用于User,一个用于{{1 }}),在DAO方法中创建事务,并将Account向下传递到EntityManager-和User-DAO /存储库。

另一种选择是在Account中创建方法transferAccount(Account account, user from, user to),在此处创建AccountDao,执行所有逻辑,然后调用transactionuserDao.save(from, em)userDao.save(to, em)