Springboot 在多线程下,处理事务;
目前很多开发的小伙伴们,都开始采用Springboot了,因为给我们带来了许多的开发便利,只需要我们关注编写逻辑代码。在工作中是会有很多小伙伴在项目逐步实用到多线程、线程池等相关技术,但是在使用多线程会出各种各样的问题;事务就是其中一种相对麻烦的事情;
大家都知道Springboot 只需要使用注解标签@Transactional 就可以使用事务了;但是往往在多线程下该处理事务的办法就失效,毫无效果;那又该如何呢?
首先大家都知道控制事务有两种方式;第一种就是刚才所说的注解式事务、第二种就是编程式事务;既然第一种失效那么我们就使用第二种方式来实现嘛;废话不多说,上代码!
package com.slsp.cloud.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.slsp.cloud.bean.User;
import com.slsp.cloud.service.UserService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 项目初始化加载
*/
@Component
@Slf4j
public class TradeApplicationRunner implements ApplicationRunner
{
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private UserService userService;
/**
* 模拟多线程下事务处理
* @param args
* @throws Exception
*/
@Override
public void run(ApplicationArguments args) throws Exception
{
//线程池
ExecutorService cachedThreadPool = Executors.newFixedThreadPool(5);
for(int i=0;i<1;i++)
{
cachedThreadPool.execute(new Runnable()
{
@SneakyThrows
public void run()
{
log.info("多线程执行;");
//开启编程式事务;
transactionTemplate.execute(new TransactionCallback<Boolean>()
{
@Override
public Boolean doInTransaction(TransactionStatus transactionStatus)
{
try
{
User usr = new User();
//随机名字
String name = UUID.randomUUID().toString().replace("-", "");
System.out.println(name);
usr.setUserName(name);
usr.setSex(1);
//插入数据库
userService.save(usr);
//模拟报错;
int i=10/0;
String name2 = UUID.randomUUID().toString().replace("-", "");
System.out.println(name2);
User usr2 = new User();
usr2.setUserName(name2);
usr2.setSex(1);
userService.save(usr2);
return true;
}
catch (Exception e)
{
//事务回滚;
transactionStatus.setRollbackOnly();
e.printStackTrace();
return false;
}
}
});
}
});
}
}
}
打完收工;简单方便;