放置在服务层

时间:2015-07-02 13:59:35

标签: spring java-ee spring-transactions transactional

我的Spring应用程序分层为Bean,Service和DAO。所有@Transactional注释都在服务层中。

这是一个特定场景中的伪代码。

UserBean.java

saveUser() {
    userService.manageUser();
}

UserServiceImpl.java

@Transactional
public void manageUser() {
    userDAO.createUser();
    userDAO.updateParentUser();
}

UserDAOImpl.java

createUser() {
    //insert user record in database
}

updateParentUser() {
    //update parent user's database record
}

在我的保存用户测试用例中,更新父用户操作在某些情况下可能会因主键违规而失败。

由于@Transactional注释是在服务类中实现的,因此仅在bean类中通知此违例异常。

在我的服务类中获取此PK违规通知的选项有哪些? [然后我可以在不同的业务流程中处理它。]

如果我在服务类中添加一个新方法并从那里调用manageUser(),则@Transactional注释将无法正常工作。这是由limitation/property of AOP引起的。 Spring期望外部调用@Transactional方法。

3 个答案:

答案 0 :(得分:2)

  1. 使用程序化事务管理并处理try catch块中的异常
  2. 介绍一个委托类,并在那里的事务中执行manageUser:

    @Transactional(REQUIRED)
    public void manageUser() {
        try{
           delegate.manageUser();
        } catch (Exception ex ) {
        //handle
        }
    }
    

    在代表班

    @Transactional(REQUIRES_NEW)
    public void manageUser() {
    }
    

答案 1 :(得分:2)

在从@Transactional方法返回之前,不会提交create / update。如果在此之前将create / update刷新到数据库,则可能在方法中获取异常,但在您的情况下,在提交之前它不会被刷新。

您可以在提交之前强制刷新创建/更新。你没有说你是在使用Hibernate还是JPA,但是session.flush()entityManager.flush()应该可以解决这个问题。

答案 2 :(得分:0)

而不是基于Spring代理的AOP我转向了AspectJ方法。这使我可以灵活地从同一服务类的另一个方法调用manageUser()方法,我可以在那里处理异常。