在我的应用程序是基于Struts2的,春天的IoC和Transasctions,JPA,休眠我要介绍的“审计日志功能”,将记录所有的重要事件,如:用户已创建/更新,或有人打开票...
我想保留这个日志在数据库中,所以为此我将有一个DAO。我还创建了一个服务类用于此目的的“AuditLogService”这将有交易行为“的传播=” REQUIRES_NEW”由于
,我要记录的事件无论是否登录事件成功与否的事实,但问题是如果我有这样的事情在我的用户服务:春天日志服务和交易
@Override
public boolean saveUser(UserDto userDto) {
User u = new User();
u.setFirstName(userDto.getFirstName());
u.setLastName(userDto.getLastName());
u.setUserName(userDto.getUserName());
u.setPassword(userDto.getPassword());
u.setIsLdapUser(userDto.getIsLdapUser());
u.setId(userDto.getId());
u.setAgentId(userDto.getAgentId());
Boolean eventStatus = true;
String event="";
try{
if (u.getId()!=null){
dao.update(u);
event = "UPDATE_USER";
}else{
dao.create(u);
event = "CREATE_USER";
}
}catch (Exception e) {
e.printStackTrace();
eventStatus = false;
return false;
}
finally {
AuditLogEvent ale = auditLogEventDao.getAuditLogEvent(event);
auditLogService.addAuditLogEvent(ale, eventStatus,u.toString());
}
return false;
}
审计日志方法提交保存用户的方法和报告该事件是真实的,但实际上该事件是假的前执行
所有。知道如何才能解决这个问题?或者,也许这种方法是不是最好的...?
更新!
Michael`s意见后,我已经改变了我的服务也成看点@Aspect @Service class AuditLogAspectImpl implements AuditLogAspect { @Autowired private AuditLogDao dao; @Autowired private UserDao userDao; @Override @AfterReturning(pointcut = "execution(* xxx.yy.services..*.save*(..))", returning = "retVal") public boolean afterLogEvent(JoinPoint joinPoint,Object retVal){ }
}
,现在我有我的方法签名喜欢这里。一切正常,我可以检测到一个操作失败或成功,我可以登录到一个日志文件,但如果我想通过dao类从数据库登录到表中,当操作失败和事务处理没有插入我的审核条目。
首先,我认为这是因为两个操作,需要审计的实际方法和审计事件都在同一个事务上下文中运行,并且如果其中一个回滚了整个事务,并且我有为方面日志记录部分创建了一个新事务。但这似乎不起作用。
任何ideea为什么?
感谢提示,但新问题呢? – 2012-07-26 11:50:29
Spring AOP是基于默认接口代理的。这意味着,来自外部的电话使用代理,这很好。该交易引入了代理以及AOP。这里没问题。但是AOP代理调用原始服务addAuditLogEvent,并且事务可能不会被应用。您需要:您的审计方面和单独的服务。 Autowire服务的方面。 – 2012-07-26 13:26:20
太好了,我跟着你的建议,并创建一个新的服务,这是执行REQUIRED_NEW交易一切都按预期工作 – 2012-07-27 05:21:53