我在Spring上跟隨了dynamic datasource routing教程的教程。對於我不得不延長AbstractRoutingDataSource告訴春天要獲取的數據源,所以我做的:在春天設置和獲取會話綁定屬性
public class CustomRouter extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
一切順利,直到我找到該類負責保存customerType的值(它應該是在同一整個會話):
public class CustomerContextHolder {
private static final ThreadLocal<Integer> contextHolder = new ThreadLocal<Integer>();
public static void setCustomerType(Integer customerType) {
contextHolder.set(customerType);
}
public static Integer getCustomerType() {
return (Integer) contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
這將創建一個線程綁定變量customerType,但我和春天有個和JSF的Web應用程序,我不認爲使用線程但會議。所以我把它設置在線程A(查看),但後來線程B(Hibernate)請求值來知道使用什麼數據源,它確實是null
的登錄頁面,因爲它具有此線程的新值。
有沒有辦法做到這一點會話有界而不是線程有界?
事情我至今嘗試過:
- 注入CustomRouter在將其設置在會話視圖:不工作,它會導致依賴條件週期
- 一個整數替換
ThreadLocal
:不工作,該值始終由最後一位用戶登錄設置
爲什麼在另一個線程中執行hibernate? – ElderMael
不是嗎?當我調試DAO方法時,我發現每次都有一個不同的線程訪問這個方法。這是錯的嗎? –
據我所知,servlet容器爲每個請求使用一個線程,這意味着當發出一個HTTP請求時,將創建一個線程或從一個池中檢索線程以便爲其提供服務,並僅爲其提供一個線程。因此,只有當該線程正在服務於不同的請求時,訪問該方法的不同線程纔可以。 – ElderMael