在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java/ java怎么控制多線程的事務??

java怎么控制多線程的事務??

就是幾個線程的結(jié)果如果都成功了,就一起提交。如果有一個失敗就全部回滾,并給出相關提示信息?網(wǎng)上沒找到比較好的方案

回答
編輯回答
不歸路

CountDownLatch
加上一個封裝 transaction 和 state 的 queue 每個線程執(zhí)行時,去隊列中拿一個事務,執(zhí)行完finally 扔回去并 count() , 并設置state = true;
最后在主線程判斷所有transaction 的state 都是true ,然后就全部提交

2017年5月25日 04:27
編輯回答
莓森

CycleBarrier可能用得上。

2017年5月24日 09:07
編輯回答
忠妾

在主方法new 一個InheritableThreadLocal 并設值為true,線程中如果出錯則把值改為false。線程全部執(zhí)行完之后,判斷InheritableThreadLocal 的值,如果為false,你就手動拋出異常聲明式回滾,或者自己寫手動回滾。這樣應該可以達到你的要求吧

2018年9月17日 08:33
編輯回答
夢囈

多個線程好解決,樓主想問的是不同進程怎么同步事務吧,比如多個dubbo服務。
確實有這個問題,首先有這樣的技術,可以強一致,但效率犧牲太多,很少有公司這么干;大多數(shù)做法都是:服務A提交后,在某個東西(比如zookeeper)上記錄節(jié)點;服務B提交后,記錄另一個節(jié)點(這些節(jié)點都在表示本次事務的樹枝節(jié)點下)……后續(xù)有個監(jiān)聽器類的東西,檢查樹枝節(jié)點下的節(jié)點數(shù)、狀態(tài)等,如果有問題分別回滾或重試或人工干預等等……

2017年6月30日 12:22
編輯回答
墨染殤

并不是所有操作都能事務化啊,首先你得自己實現(xiàn)回滾操作再談多線程事務吧。
可以用Future來保存多個異步操作,在循環(huán)中輪詢所有Future,如果全部正常結(jié)束,則提交,如任何一個拋出異常,則調(diào)用所有異步操作對應的回滾操作。

2017年6月20日 23:08
編輯回答
北城荒

我先用中文描述一下思路(假設有3個線程):

  • 設置一個共享變量,記錄成功個數(shù)

    • successCounter,對于單個線程來說,如果成功了就對這個變量++;否則,已失敗,不必再等。
  • 等待

    • 等3個線程都執(zhí)行完
  • 判斷結(jié)果

    • 如果successCounter等于3,整體成功。否則,失敗。

代碼:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class App {
    public static void main(String[] args) {
        // 線程個數(shù)
        final int SIZE = 3;

        // 交給單個線程處理,成功了就加1
        final AtomicInteger successCounter = new AtomicInteger();

        final CountDownLatch latch = new CountDownLatch(SIZE);

        final ExecutorService pool = Executors.newCachedThreadPool();

        for (int i = 0; i < SIZE; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    final boolean success = Math.random() > 0.1;
                    System.out.println(
                            Thread.currentThread().getName() +
                                    ", success = " + success);
                    if (success) {
                        // 單個成功
                        successCounter.getAndIncrement();
                        latch.countDown();
                    } else {
                        // 單個失敗,亦整體失敗
                        while (latch.getCount() > 0) {
                            latch.countDown();
                        }
                    }
                }
            });
        }

        pool.shutdown();

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("成功的線程個數(shù): " + successCounter);

        if (successCounter.get() == SIZE) {
            System.out.println("整體成功");
        } else {
            System.out.println("整體失敗");
        }
    }
}

成功的case:

pool-1-thread-1, success = true
pool-1-thread-3, success = true
pool-1-thread-2, success = true
成功的線程個數(shù): 3
整體成功

失敗的case:

pool-1-thread-1, success = true
pool-1-thread-2, success = false
pool-1-thread-3, success = true
成功的線程個數(shù): 2
整體失敗
2017年9月11日 23:00
編輯回答
老梗

數(shù)據(jù)庫事務多線程比較麻煩,因為:

  1. 這會占用大量數(shù)據(jù)庫連接;
  2. 不能用線程池,因為線程運行到最后必須等待協(xié)調(diào),要么回滾要么提交。
2018年2月1日 18:51
編輯回答
執(zhí)念

通過一個線程安全的標志狀態(tài)來同步吧

2018年5月5日 18:26