2011-09-06 11 views
5

Używam AbstractRoutingDataSource z wielkim sukcesem, ale trafiłem na problem, którego nie potrafię rozwiązać: gdy uruchamiam asynchroniczną metodę przy użyciu @Async, to traci kontekst wątku lokalnego, i Nie mogę znaleźć miejsca na ustawienie przełącznika kontekstu bazy danych. Zwykle robię to w aspekcie lub w HandlerInterceptor, ale @Async nie przechodzi przez żadną z tych zwykłych tras. Czy istnieje przechwytywacz lub coś podobnego mogę skonfigurować do uruchamiania na początku i końcu połączenia asynch, aby można było ustawić kontekst bazy danych?Spring @Aync i AbstractRoutingDataSource

Znaleźliśmy podobne pytanie na wiosennych forach dyskusyjnych. Brak odpowiedzi, choć: http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean

EDIT: Mam debugowany przepływ wykonania, a źródło AbstractRoutingData jest w rzeczywistości coraz nazywa asynchroniczny w wątku, ale jest coraz wezwany przed aspekt nazywa się zaczyna, więc DataSource jest już ustawione w sesji hibernacji przed ustawieniem wartości dla wartości . Patrząc na kod źródłowy dla AsyncExecutionInterceptor, który wspiera @Async, jest to spowodowane tym, że przechwytujący zwraca wartość Order jako , więc jego wywoływanie następuje przed cokolwiek innego.

enter image description here

Odpowiedz

2

Pomyśl Znalazłem odpowiedź: wykonanie metoda przechwytywania nie uda się ustawić zmienną na ThreadLocal, jak AsyncExecutionInterceptor zawsze mają wyższy priorytet i rozpocząć transakcję hibernacji. Zamiast tego, dokonałem eksterioryzacji logiki z metody asynchronicznej do jej własnej klasy i oznaczyłem tę metodę jako wymagającą własnej transakcji, poprzez @Transactional(propagation=Propagation.REQUIRES_NEW). Ponieważ metoda podrzędna działa teraz we własnej transakcji, zmienna na ThreadLocal została poprawnie pobrana przez AbstractRoutingDataSource na początku nowej transakcji hibernacji.