前置知识
- Spring 事务默认只在发生未捕获的
RuntimeException
时才回滚 - Spring AOP 异常捕获需要被拦截的方法显式的抛出异常。默认情况下 AOP 只捕获
RuntimeException
类的异常,但可以通过配置来捕获特定的异常
手动控制事务案例
在日常开发中,如果没办法使用 @Transactional
注解时(比如手动进行了 try catch、多线程操作、设置回滚点等)就得进行手动的编程式事务管理了
1.手动回滚try catch的异常处理
在try catch块中如果需要对事务进行回滚,就得强制使用Spring提供的事务切面类 TransactionAspectSupport
@Transactional
public void saveOmsOutboundOrder(OmsOutboundOrder order) {
try {
omsOutboundOrderDao.save(order);
//模拟异常
int sum = 1 / 0;
}catch (Exception e){
log.error("saveOmsOutboundOrder出现异常: ", e);
//手动强制回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
2.回滚到保存点
如果开启了一个事务,并且已经输入了很多的语句时,如果忽然发现上一条语句有问题,可以用 rollback 语句来让数据库状态恢复到事务执行之前的样子,然后一切再重来。因为这个问题,MySQL 提出了一个保存点 savepoint 的概念,就是在事务对应的数据库语句中打几个点,在调用 rollback 语句时能指定回滚到哪个点,而不是最初的原点
@Transactional
public void saveOmsOutboundOrder(OmsOutboundOrder order,OmsOutboundOrderDetail orderDetail) {
Object savepoint = null;
try {
omsOutboundOrderDao.save(order);
//设置保存点
savepoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
orderDetail.setOrderId(order.getId());
omsOutboundOrderDao.save(orderDetail);
//模拟异常
int sum = 1 / 0;
}catch (Exception e){
log.error("saveOmsOutboundOrder出现异常: ", e);
//手动强制回滚事务到保存点
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savepoint);
}
}
3.DataSourceTransactionManager
Spring 的事务处理中,通用的事务处理流程是由抽象事务管理器 AbstractPlatformTransactionManager
来提供的,由 PlatformTransactionManager
的具体实现类来实现
@Autowired
private DataSourceTransactionManager transactionManager;
//@Autowired
//private DataSourceTransactionManager transactionManager;
@Transactional
public void saveOmsOutboundOrder(OmsOutboundOrder order) {
//TransactionStatus transaction = transactionManager.getTransaction(TransactionDefinition.withDefaults());
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehaviorName("PROPAGATION_REQUIRED");
TransactionStatus transaction = transactionManager.getTransaction(definition);
try {
omsOutboundOrderDao.save(order);
//模拟异常
int sum = 1 / 0;
transactionManager.commit(transaction);
}catch (Exception e){
log.error("saveOmsOutboundOrder出现异常: ", e);
//手动控制回滚异常
transactionManager.rollback(transaction);
}
}
标签:回滚,手动,SpringBoot,编程,事务,try,catch,order
From: https://www.cnblogs.com/52-IT-y/p/18106038