春季日志服务和交易

时间:2012-07-25 08:16:42

标签: spring spring-transactions

在我的应用程序中基于struts2,Spring IoC和Transasctions,jpa,Hibernate我想引入一个“审计日志功能”,它将记录所有重要事件,例如:用户已被创建/更新,或者有人打开了一张票...... 我想将这个日志保存在数据库中,所以为此我将有一个DAO。我还为此创建了一个服务类'AuditLogService',它将具有事务行为“propagation =”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的建议之后,我将我的服务转变为一个方面

    @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 个答案:

答案 0 :(得分:1)

方法不正确,因为声明性事务是通过around advice(AOP)实现的,所以整个方法执行,包括你的审计finally块,然后返回并提交事务。

我建议您编写自己的审核方面,因为审核或日志记录是横切问题的主要示例。

查看Aspect Oriented Programming with Spring

我选择After (finally) advice,以便您可以审核失败的成功资料。

实际上并不复杂......你不会需要AspectJ,Spring Aspects足以满足特定目的。

相关问题