我的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方法。
答案 0 :(得分: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()方法,我可以在那里处理异常。