Spring@事务性问题/挑战,同时放置在服务层
我的Spring应用程序分层为Bean、服务和DAO。所有@Transactional注释都在服务层中 这是一个特定场景中的伪代码 UserBean.javaSpring@事务性问题/挑战,同时放置在服务层,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(); }
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运行良好。现在我可以在服务类中处理异常了。非常感谢。