处理springboot 下提交事务异常,数据库没有回滚的问题。

spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

什么是检查型异常什么又是非检查型异常?
最简单的判断点有两个:
1.继承自runtimeexception或error的是非检查型异常,而继承自exception的则是检查型异常(当然,runtimeexception本身也是exception的子类)。

2.对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。所以必须在service捕获异常,然后再次抛出,这样事务方才起效。

结论:

在spring的事务管理环境下,使用unckecked
exception可以极大地简化异常的处理,只需要在事务层声明可能抛出的异常(这里的异常可以是自定义的unckecked
exception体系),在所有的中间层都只是需要简单throws即可,不需要捕捉和处理,直接到最高层,比如UI层再进行异常的捕捉和处理。

默认规则:

1 让checked例外也回滚: @Transactional(rollbackFor=Exception.class),一般只需添加这个即可

2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED),或者不添加

注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。因为一旦你try{}catch{}了。系统会认为你已经手动处理了异常,就不会进行回滚操作。

示例:

1 @Override
2 @Transactional(rollbackFor = Exception.class)
3 public Integer submitOrder(FlashbuyOrder flashbuyOrder, List<FlashbuyOrderItem> itemList)
4 throws Exception
5 {
6
7 return null;
8
9 }

示例

 spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

https://www.cnblogs.com/liuzhenlei/p/6777644.html

 1  //假设这是一个service类的片段
2
3 try{
4 //出现异常
5 } catch (Exception e) {
6 e.printStackTrace();
7 //设置手动回滚
8 TransactionAspectSupport.currentTransactionStatus()
9 .setRollbackOnly();
10 }
11 //此时return语句能够执行
12 return xxx;

如上:

  当我们需要在事务控制的service层类中使用try catch 去捕获异常后,就会使事务控制失效,因为该类的异常并没有抛出,就不是触发事务管理机制。怎样才能即使用try catch去捕获异常,而又让出现异常后spring回滚呢,这里就要用到

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

完美解决问题。并且能够使该方法执行完。

这个需要注意两点:

1. 方法上要加上    @Transactional(rollbackFor = Exception.class)   再配合TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 才可以,

否则会报错  NoTransactionException: No transaction aspect-managed TransactionStatus in scope

    at

@Transactional(propagation = Propagation.REQUIRES_NEW,
rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
public void testInsert(int index) throws Exception {
OrderDO orderDO = new OrderDO();
orderDO.setThirdOrderId("1000");
int rowCount = this.orderMapper.insertOrder(orderDO);
if (index == 1) {
throw new RuntimeException("wrong");
}
if (index == 2) {
throw new Exception("wrong");
}
if (index == 3) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}

2.  Spring Transactional一直是RD的事务神器,但是如果用不好,反会伤了自己。下面总结@Transactional经常遇到的几个场景:

@Transactional 加于private方法, 无效
@Transactional 加于未加入接口的public方法, 再通过普通接口方法调用, 无效
@Transactional 加于接口方法, 无论下面调用的是private或public方法, 都有效
@Transactional 加于接口方法后, 被本类普通接口方法直接调用, 无效
@Transactional 加于接口方法后, 被本类普通接口方法通过接口调用, 有效
@Transactional 加于接口方法后, 被它类的接口方法调用, 有效
@Transactional 加于接口方法后, 被它类的私有方法调用后, 有效

Transactional是否生效, 仅取决于是否加载于接口方法, 并且是否通过接口方法调用(而不是本类调用)。

https://segmentfault.com/a/1190000014617571

 ProductService.java
/**********************************************************************/
public interface ProductService{
Integer getPrice(ProductInfo p);
Integer compute(ProductInfo p);
}
/**********************************************************************/ ProductServiceImpl.java
/**********************************************************************/
@Service
public class ProductServiceImpl implements ProductService{
@Autowired
private ProductService productService; public Integer getPrice(ProductInfo p){
productService.compute(p);
} @Transactional(rollbackFor = Exception.class)
public Integer compute(ProductInfo p){
try{
...
}catch(Exception e){
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return 0;
}
}
} 是可以的,因为是通过接口调用了

 ProductService.java
/**********************************************************************/
public interface ProductService{
Integer getPrice(ProductInfo p); } public interface MyService{ Integer compute(ProductInfo p);
}
/**********************************************************************/ ProductServiceImpl.java
/**********************************************************************/
@Service
public class ProductServiceImpl implements ProductService{
@Autowired
private MyService myService ; public Integer getPrice(ProductInfo p){
myService.compute(p);
} } @Service
public class MyServiceImpl implements MyService{ @Transactional(rollbackFor = Exception.class)
public Integer compute(ProductInfo p){
try{
...
}catch(Exception e){
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return 0;
}
}
} 放在两个接口类里面,然后通过接口方法调用,是可以生效的

3.在web项目中,很多时候要用到@Transactional 注解方法或者类进行事务处理,自动事务提交有时候就会有问题,这个时候就要用到手动进行事务提交 ,在try catch 异常抛出里面手动回滚事务处理TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

使用Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); 设置回滚点,

使用TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);回滚到savePoint。

转自:

https://blog.csdn.net/zhuchunyan_aijia/article/details/80191534

https://blog.csdn.net/xuhaogang3/article/details/82190026

SpringBoot事务注解@Transactional 事物回滚、手动回滚事物的更多相关文章

  1. SpringBoot事务注解@Transactional

    SpringBoot提供了非常方便的事务操作,通过注解就可以实现事务的回滚,非常方便快捷,下面我们就说一下如何进行事务操作. 1. 事务说明 在Spring中,事务有两种实现方式,分别是编程式事务管理 ...

  2. Springboot 事务注解--- @Transactional

    spring boot @Transactional事物处理    spring boot 添加事物使用 @Transactional注解 简单使用 在启动类上方添加 @EnableTransacti ...

  3. 《四 spring源码》spring的事务注解@Transactional 原理分析

    先了解什么是注解 注解 Jdk1.5新增新技术,注解.很多框架为了简化代码,都会提供有些注解.可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件. 注解不会也不能影 ...

  4. SpringBoot事务注解详解

    @Transactional spring 事务注解 1.简单开启事务管理 @EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:ann ...

  5. 26.SpringBoot事务注解详解

    转自:https://www.cnblogs.com/kesimin/p/9546225.html @Transactional spring 事务注解 1.简单开启事务管理 @EnableTrans ...

  6. JPA的事务注解@Transactional使用总结

    在项目开发过程中,如果您的项目中使用了Spring的@Transactional注解,有时候会出现一些奇怪的问题,例如: 明明抛了异常却不回滚? 嵌套事务执行报错? ...等等 很多的问题都是没有全面 ...

  7. Spring学习之事务注解@Transactional

    今天学习spring中的事务注解,在学习Spring注解事务之前需要明白一些事务的基本概念: 事务:并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通 ...

  8. Spring事务注解@Transactional回滚问题

    Spring配置文件,声明事务时,如果rollback-for属性没有指定异常或者默认不写:经测试事务只回滚运行时异常(RuntimeException)和错误(Error). <!-- 配置事 ...

  9. Spring 事务注解@Transactional

    事务管理一般有编程式和声明式两种,编程式是直接在代码中进行编写事物处理过程,而声名式则是通过注解方式或者是在xml文件中进行配置,相对编程式很方便. 而注解方式通过@Transactional 是常见 ...

  10. Spring事务注解@Transactional失效的问题

    在项目中发现事务失效,使用@Transactional注解标注的Service业务层实现类方法全部不能回滚事务了,最终发现使用因为Spring与shiro进行整合之后导致的问题,将所有的Service ...

随机推荐

  1. [转帖]ssd/san/sas/磁盘/光纤/RAID性能比较

    https://plantegg.github.io/2022/01/25/ssd_san%E5%92%8Csas%E7%A3%81%E7%9B%98%E6%80%A7%E8%83%BD%E6%AF% ...

  2. iPhone 使用类ChatGPT应用的几种方法

    iPhone 使用类ChatGPT功能的几种方法 背景 前几天使用edge的wetab的插件给自己的工作带来了很多帮助 尤其是一些基础shell语法以及sql语法, 比使用百度, bing 等搜素引擎 ...

  3. [转帖]Kafka关键参数设置

    https://www.cnblogs.com/wwcom123/p/11181680.html 生产环境中使用Kafka,参数调优非常重要,而Kafka参数众多,我们的java的Configurat ...

  4. [转帖]解决vCenter6.x由于证书过期问题无法登录

    https://www.dinghui.org/vcenter-sts-certificate.html#:~:text=%E8%BF%99%E6%97%B6%E5%80%99%EF%BC%8C%E5 ...

  5. [转帖] 常见的Socket网络异常场景分析

    https://www.cnblogs.com/codelogs/p/16001770.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 在目前微服务的 ...

  6. Sysbench 开启超线程/关闭超线程以及容器运行数据库的性能损耗

    Sysbench 开启超线程/关闭超线程性能损耗 摘要 Stress-NG 测试完之后 突然想 使用sysbenchen也进行一次压测 验证一把 超线程对数据的性能影响. 压测命令 ./sysbenc ...

  7. 学习下Redis内存模型

    作者:京东零售 吴佳 前言 redis,对于一个java开发工程师来讲,其实算不得什么复杂新奇的技术,但可能也很少人去深入了解学习它的底层的一些东西.下面将通过对内存统计.内存划分.存储细节.对象类型 ...

  8. 【主流技术】实战之 Spring Boot 中集成微信支付(小程序)

    前言 微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的. 以下是经过真实商业项目实践的集成步骤,包括注册流程.调用过程.代码demo(经过脱敏)等,希望我的分享 ...

  9. 深度学习应用篇-推荐系统[11]:推荐系统的组成、场景转化指标(pv点击率,uv点击率,曝光点击率)、用户数据指标等评价指标详解

    深度学习应用篇-推荐系统[11]:推荐系统的组成.场景转化指标(pv点击率,uv点击率,曝光点击率).用户数据指标等评价指标详解 1. 推荐系统介绍 在网络技术不断发展和电子商务规模不断扩大的背景下, ...

  10. 机器学习算法(三):基于horse-colic数据的KNN近邻(k-nearest neighbors)预测分类

    机器学习算法(三):基于horse-colic数据的KNN近邻(k-nearest neighbors)预测分类 项目链接参考:https://www.heywhale.com/home/column ...