- 多线程事物:
原因:多线程,每个线程都和数据库有一个连接,不同的连接事物不统一
核心思想:记录每个线程的事物状态,有一个异常,所有线程统一回滚。
方案:我强制手动把每个线程的事务状态放到一个同步集合里面。然后如果有单个异常,循环回滚每个线程。
List<TransactionStatus> transactionStatuses = Collections.synchronizedList(new ArrayList<TransactionStatus>());
@Override
@Transactional
public void save(String companyId, List<GradeLevelDTO> gradeLevelDTOList) {
try {
handle(companyId, gradeLevelDTOList);
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
private void handle(String companyId, List<GradeLevelDTO> gradeLevelDTOList) {
new AsyncTaskUtil().runTask(new AsyncTask() {
@Override
public Object run() {
threadTranscation();
GradeLevel gradeLevel = BeanConvertUtils.convertFor(gradeLevelDTOList.get(0), new GradeLevel());
gradeLevel.setCompanyId(companyId);
GradeLevel save = gradeLevelDao.save(gradeLevel);
return save;
}
});
new AsyncTaskUtil().runTask(new AsyncTask() {
@Override
public Object run() {
threadTranscation();
String str = null;
str.trim();
GradeLevel gradeLevel = BeanConvertUtils.convertFor(gradeLevelDTOList.get(1), new GradeLevel());
gradeLevel.setCompanyId(companyId);
GradeLevel save = gradeLevelDao.save(gradeLevel);
return save;
}
});
}
private void threadTranscation() {
// 使用这种方式将事务状态都放在同一个事务里面
DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别,开启新事务,这样会比较安全些。
TransactionStatus transaction = transactionManager.getTransaction(defaultTransactionDefinition); // 获得事务状态
transactionStatuses.add(transaction);
}
参考:https://www.cnblogs.com/super-chao/p/11177558.html