1. 程式人生 > >Spring裡多執行緒共享事務的問題

Spring裡多執行緒共享事務的問題

最近做Performance Tuning, 有一個功能,在使用者點選後要做兩次資料庫儲存,而且還要傳送好幾條JMS message,造成反應極慢。所以我考慮用FutureTask來併發做幾件事情,我在service層裡新建FutureTask。寫完後,測試發現除了還在原來主執行緒中的資料庫操作外,其他資料庫,message操作通通變成不受事務控制的了。

研究Spring原始碼,發現原來Spring事務是通過ThreadLocal類來實現的,在TransactionSynchronizationManager中有兩個方法:

public static void bindResource(Object key, Object value) throws IllegalStateException

public static Object getResource(Object key)

分別用來繫結和獲得對應執行緒的事務控制例項。所以對於不同的執行緒,預設來說肯定會有不用的事務控制。我們的事務控制是通過aop加在service層上的,所以只有那個主執行緒才有事務,而後來建立的FutureTask由於沒有經過AOP的程式碼,所以就沒事務控制了。

問題:能把同一事務控制加到多個執行緒中嗎?理論上是可以的,我們可以在建立執行緒前在主執行緒中通過getResource方法把物件獲取出來,傳入新建立的執行緒,讓後用bindResource方法繫結上去。這樣會有問題嗎?上網查了下,發現還是有潛在問題的,因為資料庫的操作,只支援單執行緒下保證事務正確,如果多個執行緒操作同一事務就會出問題,要保證不出錯,就必須確保更新資料庫的方法是同步的,也就是一次只能一個執行緒操作資料庫(想想還是挺麻煩的,因為我們現在都用spring的template)。但是如果事務是JTA的呢,因為操作的是不同的資料庫,或者資料庫和JMS(我們的資料庫操作和JMS不在同一事務中,以後有時間可以談談),是不是就可以同步操作呢?

    我想應該是可以的吧,對於事務擴充套件到多個執行緒的問題,都是我的猜想,有空大家可以去試試。哪位如果認為我說的不對,歡迎指點!!