struts2、Spring IoC、およびTransasctions、jpa、Hibernateに基づく私のアプリでは、ユーザーが作成/更新された、またはチケットが作成されたなど、すべての重要なイベントを記録する「監査ログ機能」を導入したいと考えています誰かが開いた...
このログをデータベースに保存したいので、DAO を用意します。
ログに記録されたイベントが成功したかどうかに関係なく、イベントをログに記録したいという事実のために、この目的のために「AuditLogService」というサービス クラスも作成しました。ユーザーサービスに次のようなものがあります:
@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;
}
監査ログ メソッドはユーザー保存メソッドをコミットする前に実行され、イベントが true であったと報告しますが、実際にはイベントは false でした。
どうすればこれを解決できますか?それとも、このアプローチは最善ではありません...?
アップデート!
マイケルのアドバイスの後、私は自分のサービスをアスペクトにも変えました@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 クラスを介してデータベースからテーブルに記録したい場合は、操作が失敗し、トランザクションがロールされます。私の監査エントリが挿入されていません。
最初に、監査が必要な実際のメソッドと監査イベントの両方の操作が同じトランザクションコンテキストで実行されているため、これが発生していると考えました。そのうちの1つがロールバックされた場合、トランザクション全体がロールバックされ、アスペクト ロギング部分の新しいトランザクション。しかし、これはうまくいかないようです。
理由はありますか?