2011-05-26 41 views
1

我有一個審計日誌記錄攔截器,基本上設置了兩個字段modified_by和created_by。例如,hibernateTemplate,具有狀態和線程的entityInterceptor

public void update(DomainEntity entity, Integer userId) { 
    template.update(audited(entity, userId)); 
} 

private DomainEntity audited(DomainEntity entity, Integer userId) { 
    template.setEntityInterceptor(new AuditInterceptor(userId)); 
    return entity; 
} 

所以我創建一個有問題的用戶id一個新的攔截器,並設置它在模板上每個審計DAO操作。我擔心她有一個併發問題,因爲兩個線程可能會將攔截器設置在同一個模板上,從而搞砸了一切。

避免這種情況的最佳解決方案是什麼? userId是攔截器需要知道的狀態。任何替代設計?

回答

1

讓servlet篩選器將userid存儲在ThreadLocal中,並讓攔截器使用它。

+0

不在servlet-land中,不幸的是......每個請求都包含服務器用來查找用戶標識的會話標識符。因此,來自同一用戶的請求將由不同的線程處理 – ThuneGrill 2011-05-26 14:53:50

+0

@ThuneGill:這是相同的概念,但是,不是嗎?你有一些查找用戶標識的前端控制器。 – 2011-05-26 15:01:07

+0

是的,我猜。謝謝! – ThuneGrill 2011-05-26 15:25:30

1

@nathan提出了一種先進的方法。如果你想要一個更簡單的替代方案,爲什麼不能有一個通用的攔截器,它根據可審計類的Map來查找合適的代理。代表們將共享通用攔截器知道的通用接口。如果在通用攔截器中避免使用狀態,則不存在線程問題。此外,就像您目前的方法,您可以單獨測試攔截器。