事务回滚

package com.test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

public class Test {

	private static ExecutorService exec = Executors.newCachedThreadPool();

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		CountDownLatch mainThreadCount = new CountDownLatch(10);
		CountDownLatch rollBackCount = new CountDownLatch(1);
		AtomicBoolean rollbackFlag = new AtomicBoolean(false);
		for (int i = 0; i < 10; i++) {
			exec.execute(new TaskWithoutResult(i, mainThreadCount, rollBackCount, rollbackFlag));
		}

		// 主线程业务执行完毕 如果其他线程也执行完毕 且没有报异常 正在阻塞状态中 唤醒其他线程 提交所有的事务
		// 如果其他线程或者主线程报错 则不会进入if 会触发回滚
		if (!rollbackFlag.get()) {
			mainThreadCount.await();
			rollBackCount.countDown();
		}
	}
}
package com.test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

class TaskWithoutResult implements Runnable {

	private int id;
	private CountDownLatch mainThreadCount;
	private CountDownLatch rollBackCount;
	private AtomicBoolean rollbackFlag;

	public TaskWithoutResult(int id, CountDownLatch cout, CountDownLatch rollBackCount, AtomicBoolean rollbackFlag) {
		this.id = id;
		this.mainThreadCount = cout;
		this.rollBackCount = rollBackCount;
		this.rollbackFlag = rollbackFlag;
	}

	@Override
	public void run() {
		if (rollbackFlag.get()) {
			return;
		}
		try {
			Thread.sleep(1000 * id);
			if (id == 3) {
				//int a = id / 0;
			}
			mainThreadCount.countDown();
			rollBackCount.await();// 我执行完了,我等着看别人执行结果是不是有回滚
			if (rollbackFlag.get()) {
				System.out.println("线程" + id + "回滚事务");
				// 回滚
			} else {
				// 提交我的事务
				System.out.println("线程" + id + "提交事务");
			}
		} catch (Exception ex) {
			// 如果出错了 就放开锁 让别的线程进入提交/回滚 本线程进行回滚
			rollbackFlag.set(true);
			rollBackCount.countDown();
			mainThreadCount.countDown();
			// 自己出错了要回滚自己
			///////////
			System.out.println("线程" + id + "回滚事务");
		}
	}
}

  

posted @ 2020-11-09 17:18  天冷吃冰棍儿  阅读(100)  评论(0编辑  收藏  举报