2012-07-25 145 views
1

在我的应用程序是基于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为什么?

回答

1

的做法是不正确的,因为声明式事务是通过环绕通知(AOP),所以整个方法执行,包括你终于与审计块,则回报和事务被提交执行。

我建议你写你自己的审核方面,因为像审计或日志是横切关注一个典型的例子。

看一看Aspect Oriented Programming with Spring

我与After (finally) advice这样你就可以审核失败和成功的东西去了。

它实际上不是那么复杂......你并不需要的AspectJ,春节因素将足以为特定目的。

+0

感谢提示,但新问题呢? – 2012-07-26 11:50:29

+0

Spring AOP是基于默认接口代理的。这意味着,来自外部的电话使用代理,这很好。该交易引入了代理以及AOP。这里没问题。但是AOP代理调用原始服务addAuditLogEvent,并且事务可能不会被应用。您需要:您的审计方面和单独的服务。 Autowire服务的方面。 – 2012-07-26 13:26:20

+0

太好了,我跟着你的建议,并创建一个新的服务,这是执行REQUIRED_NEW交易一切都按预期工作 – 2012-07-27 05:21:53