Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring@事务性问题/挑战,同时放置在服务层_Spring_Jakarta Ee_Spring Transactions_Transactional - Fatal编程技术网

Spring@事务性问题/挑战,同时放置在服务层

Spring@事务性问题/挑战,同时放置在服务层,spring,jakarta-ee,spring-transactions,transactional,Spring,Jakarta Ee,Spring Transactions,Transactional,我的Spring应用程序分层为Bean、服务和DAO。所有@Transactional注释都在服务层中 这是一个特定场景中的伪代码 UserBean.java saveUser() { userService.manageUser(); } UserServiceImpl.java @Transactional public void manageUser() { userDAO.createUser(); userDAO.updateParentUser(); }

我的Spring应用程序分层为Bean、服务和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注释将无法正常工作。这是由于。Spring期望外部调用@Transactional方法

在try-catch块中使用编程事务管理和处理异常 引入一个委托类并在其中的事务中执行manageUser:

@Transactional(REQUIRED)
public void manageUser() {
    try{
       delegate.manageUser();
    } catch (Exception ex ) {
    //handle
    }
}
和在代理类中

@Transactional(REQUIRES_NEW)
public void manageUser() {
}
在try-catch块中使用编程事务管理和处理异常 引入一个委托类并在其中的事务中执行manageUser:

@Transactional(REQUIRED)
public void manageUser() {
    try{
       delegate.manageUser();
    } catch (Exception ex ) {
    //handle
    }
}
和在代理类中

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

在从@Transactional方法返回之前,不会提交创建/更新。如果在此之前已将创建/更新刷新到数据库中,那么您可能会在该方法中获得异常,但在您的情况下,在提交之前不会刷新该异常


您可以在提交之前强制刷新创建/更新。您不会说您是在使用Hibernate还是JPA,但session.flush或entityManager.flush应该可以做到这一点。

在您从@Transactional方法返回之前,不会提交创建/更新。如果在此之前已将创建/更新刷新到数据库中,那么您可能会在该方法中获得异常,但在您的情况下,在提交之前不会刷新该异常


您可以在提交之前强制刷新创建/更新。您没有说是使用Hibernate还是JPA,但session.flush或entityManager.flush应该可以做到这一点。

我没有使用基于Spring代理的AOP,而是使用AspectJ方法。这使我可以灵活地从同一服务类的另一个方法调用manageUser方法,并且我可以在那里处理异常。

我使用AspectJ方法代替基于Spring代理的AOP。这使我可以灵活地从同一服务类的另一个方法调用manageUser方法,并且我可以在那里处理异常。

当您说此违规异常将仅在bean类中通知时,您是什么意思。当然,如果异常是在服务类中引发的,那么您也可以在服务类中捕获它并正确处理它?@ConMan当@Transactional方法“退出”时会发生此异常。所以,对于当前的代码,我将无法在服务类中捕获它。当您说这个违规异常将只在bean类中被通知时,您的意思是什么。当然,如果异常是在服务类中引发的,那么您也可以在服务类中捕获它并正确处理它?@ConMan当@Transactional方法“退出”时会发生此异常。所以,以目前的代码,我将无法在服务类中捕捉到它。谢谢您的建议。不幸的是,这些选项可能不适合我的情况。编程事务管理是最不可取的。我有很多这样的场景,因为为代理层添加一个对我来说不是一个好建议。谢谢你的建议。不幸的是,这些选项可能不适合我的情况。编程事务管理是最不可取的。我有很多地方有这样的场景,因为为代理层添加一个对我来说不是一个好的建议。你一针见血!!!。我正在使用JPA,entityManager.flush运行良好。现在我可以在服务类中处理异常了。谢谢。你一针见血!!!。我正在使用JPA,entityManager.flush运行良好。现在我可以在服务类中处理异常了。非常感谢。