摘要:最近開發(fā),有地方需要用到多線程,每個線程里面處理多個方法,過程中遇到了一個問題,我們使用平時的注解,就是當前一個方法執(zhí)行完成比如插入操作,后一個方法是不會事務回滾的。
最近開發(fā),有地方需要用到多線程,每個線程里面處理多個方法,過程中遇到了一個問題,我們使用平時的@Transactional注解,就是當前一個方法執(zhí)行完成(比如插入操作),后一個方法是不會事務回滾的。當時覺得很不可思議,后來經(jīng)過半天時間,終于挖出原因,并成功解決。
我這里先說明原因:多線程底層連接數(shù)據(jù)庫的時候,時使用的線程變量(TheadLocal),所以,開多少線程理論上就會建立多少個連接,每個線程有自己的連接,事務肯定不是同一個了。
解決辦法:我強制手動把每個線程的事務狀態(tài)放到一個同步集合里面。然后如果有單個異常,循環(huán)回滾每個線程。
代碼如下:
//先在開啟多線程外面,定義一個同步集合: ListtransactionStatuses = Collections.synchronizedList(new ArrayList ()); //開啟多線程 executorService.execute(new Runnable() { @Override public void run() { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔離級別,開啟新事務,這樣會比較安全些。 TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務狀態(tài) transactionStatuses.add(status); try{ //邏輯1 ... //邏輯2 ... }catch(Exception e){ } }
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69581.html
摘要:起因及介紹在處理原始對賬文件的時候,我將數(shù)據(jù)歸類后批量存入相應的表中。結論事務只能管著開啟事務的線程,其他子線程出了問題都感知不到,所以在多線程環(huán)境操作要慎重。高頻容易搞死服務器,低頻會阻塞自身程序。重試次數(shù)和超時時間根據(jù)業(yè)務情況設置。 起因及介紹 在處理原始對賬文件的時候,我將數(shù)據(jù)歸類后批量存入相應的表中。在持久化的時候,用了parallelStream(),想著同時存入很多表這樣可...
摘要:和事務的關系關系型數(shù)據(jù)庫某些消息隊列等產(chǎn)品或中間件稱為事務性資源,因為它們本身支持事務,也能夠處理事務。事務的傳播特性,,,,,,強制要求要有一個物理事務。外圍事務不會被內(nèi)部事務的回滾狀態(tài)影響。不支持當前事務。 Spring和事務的關系 關系型數(shù)據(jù)庫、某些消息隊列等產(chǎn)品或中間件稱為事務性資源,因為它們本身支持事務,也能夠處理事務。 Spring很顯然不是事務性資源,但是它可...
閱讀 713·2023-04-25 17:54
閱讀 2972·2021-11-18 10:02
閱讀 1132·2021-09-28 09:35
閱讀 649·2021-09-22 15:18
閱讀 2847·2021-09-03 10:49
閱讀 3051·2021-08-10 09:42
閱讀 2573·2019-08-29 16:24
閱讀 1255·2019-08-29 15:08