2012-07-25 259 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