在我的應用程序是基於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