现在有10个任务,每个任务需要执行10s,用线程池并发处理,每个线程会插入数据,需求:只要有一个线程插入数据失败了,其他所有线程的数据都需要回滚。
这个是并发事务的问题,也可以说是一个分布式事务的问题,解决方案不少,这里基于一种两阶段提交的方式进行处理。
即这里主线程作为事务协调者,多个线程作为参与者,直到多个参与者全部执行了事务操作后会给协调者返回执行结果,在此期间协调者会一直阻塞,同时,参与者也会阻塞直到协调者收到所有参与者的执行结果,只有有一个参与者执行失败,协调者就会通知所有参与者都进行回滚操作,反之则提交事务。
代码如下:
建表语句:
create table `abc` (
`age` int (11)
);
Mapper接口
public interface AbcMapper {
@Insert("insert into abc values (#{val})")
int insert(@Param("val")Object val);
}
测试类
public class MapperTest {
@Autowired
private AbcMapper abcMapper;
@Autowired
private PlatformTransactionManager transactionManager;
private CountDownLatch countDownLatch = new CountDownLatch(10);
private final Object lock = new Object();
private volatile boolean commit = true;
@Test
public void tes() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 1; i <= 10; i++) {
int a = i;
executorService.execute(() -> {
Object value = a == 10 ? "a" : a;
//Object value = a ;
insert(value);
});
}
countDownLatch.await();
synchronized (lock){
lock.notifyAll();
}
}
private void insert(Object value) {
TransactionStatus txStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
abcMapper.insert(value);
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
countDownLatch.countDown();
} catch (Exception e) {
countDownLatch.countDown();
commit = false;
System.out.println(Thread.currentThread().getName() + "->error");
}
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName()+"->wait");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"->do");
System.out.println("commit:"+commit);
if (commit) {
transactionManager.commit(txStatus);
System.out.println(Thread.currentThread().getName() + "->commit");
return;
}
try {
transactionManager.rollback(txStatus);
}catch (Exception e){
System.out.println("exception:"+e.getLocalizedMessage());
}
System.out.println(Thread.currentThread().getName() + "->rollback");
}
}
执行结果如下:
pool-4-thread-10->error
pool-4-thread-10->wait
pool-4-thread-8->wait
pool-4-thread-2->wait
pool-4-thread-6->wait
pool-4-thread-5->wait
pool-4-thread-9->wait
pool-4-thread-1->wait
pool-4-thread-4->wait
pool-4-thread-3->wait
pool-4-thread-7->wait
pool-4-thread-7->do
pool-4-thread-3->do
commit:false
pool-4-thread-5->do
pool-4-thread-2->do
commit:false
pool-4-thread-1->do
commit:false
pool-4-thread-10->do
pool-4-thread-4->do
commit:false
pool-4-thread-6->do
commit:false
pool-4-thread-8->do
commit:false
pool-4-thread-9->do
commit:false
commit:false
commit:false
commit:false
pool-4-thread-10->rollback
pool-4-thread-1->rollback
pool-4-thread-5->rollback
pool-4-thread-6->rollback
pool-4-thread-2->rollback
pool-4-thread-8->rollback
pool-4-thread-4->rollback
pool-4-thread-7->rollback
pool-4-thread-9->rollback
pool-4-thread-3->rollback
所有的事务已经全部回滚,表中没有添加数据
页面更新:2024-02-23
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号