事务解决方案
Spring事务自动回滚的原理
首先了解一下Spring事务自动回滚的基本原理
当我们在方法sumitOrder上加了@Transactional,springboot会帮你生成代理类,代理类里面生成代理方法
代理方法进过一系列处理才会调用原生方法。因此当方法抛出运行时异常到外层的事务代理方法中时,异常会被捕获,在回滚事务后,异常会继续向上抛出,不影响上层正常使用。
//原生方法
@Override
@Transactional
public Object submitOrder(String s) throws Exception {
if(s == null){
throw new RuntimeException("传入的参数不能为 null");
}
}
//事务的代理
ProxysubmitOrder(){
try {
1.开启事务
2.submitOrder()
3.提交事务
} catch (Exception e) {
4.捕获到异常,回滚事务
5.throw e //将异常继续向调用方法抛出
}
实际使用中的三种方式
1.自动回滚
只要执行代码的时候抛出了运行时异常,就会自动回滚
@Transactional
public Object submitOrder(String s) throws Exception {
if(s == null){
throw new RuntimeException("传入的参数不能为 null");
}
}
2.手动回滚
编程式事务管理
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.PlatformTransactionManager; // 引入合适的事务管理器
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Service
public class MyService {
public void myTransactionalTest() {
// 创建一个事务定义实例,用于定义事务的属性
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 设置传播行为为 PROPAGATION_REQUIRED,即如果有事务正在运行,则加入该事务;否则新建一个事务
def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
// 获取当前事务的状态,如果没有事务,则新建一个事务并返回事务状态 这一步开启了事务
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 执行业务逻辑
// 这里是需要进行更复杂管理的业务逻辑
transactionManager.commit(status); // 提交事务
} catch (Exception e) {
transactionManager.rollback(status); // 回滚事务
// 可以选择将异常抛出或进行日志记录
throw e; // 可以选择重新抛出异常
}
}
}
示例:
// 创建事务属性
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
// 获取事务状态
TransactionStatus status = transactionManager.getTransaction(def);
List<List<AesOfInterface>> data = Lists.partition(collEntrieList, CommonProperties.LEN_1000);
try {
for (List<AesOfInterface> subList : data) {
//入库
rows = rows + aesOfInterfaceMapper.insertList(subList);
}
// 提交事务
transactionManager.commit(status);
}catch (Exception e){
// 回滚事务
transactionManager.rollback(status);
//返回结果
msg = "入库失败:"+e.getMessage();
logger.info(msg);
retMap.put(CommonProperties.MK_EXEC_RESULT_FLAG,false);
retMap.put(CommonProperties.MK_DATA,Long.valueOf(-1));
retMap.put(CommonProperties.MK_MSG,msg);
logger.info(e.getMessage());
return retMap;
}