多线程事务控制
spring无法对多线程进行事务控制,原因是:
多线程底层连接数据库的时候,是使用的线程变量(TheadLocal),所以,开多少线程理论上就会建立多少个连接,每个线程有自己的连接,事务肯定不是同一个了。
解决办法:我强制手动把每个线程的事务状态放到一个同步集合里面。然后如果有单个异常,循环回滚每个线程。
假如service中的一个方法由以下逻辑构成:
1.前面的是调用多线程前的操作
2.调用多线程的操作
假设其中任何一个与数据库的更新操作发生了异常,想要整体回滚怎么办?那么就要用到以下的方式了:
List<TransactionStatus> transactionStatuses = Collections.synchronizedList(new ArrayList<TransactionStatus>()); // 在每组逻辑操作之前加入以下代码 // 使用这种方式将事务状态都放在同一个事务里面 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。 TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
详细DEMO:
TestServiceImpl:
package com.test.impl; import com.test.entity.User2; import com.test.entity.User3; import com.test.mapper.User2Mapper; import com.test.mapper.User3Mapper; import com.test.service.TestBService; import com.test.service.TestService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.support.DefaultTransactionDefinition; import java.util.ArrayList; import java.util.Collections; import java.