SpringBoot中@Transiactional注解没有效果的解决

 更新时间:2021年8月19日 16:00  点击:1640

SpringBoot @Transiactional注解没有效果

背景

数据库为mysql

问题

使用SpringBoot操作数据库插入两条数据,service层的方法出现了异常,按理说两条数据都该插不进去的,可以数据库中却还是有一条数据。

数据库表格式:

这里写图片描述

service层代码:

package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.domain.Girl;
import com.example.demo.repository.GirlRepository;
@Service
public class GirlService {
    @Autowired
    private GirlRepository girlRepository;
    @Transactional
    public void transiactionTest() {
        Girl g1 = new Girl();
        g1.setAge(33);
        g1.setCupSize("B");
        girlRepository.save(g1);
        Girl g2 = new Girl();
        g2.setAge(33);
        g2.setCupSize("FFFFF");  // 长度和数据库的长度不符,会出异常
        girlRepository.save(g2);
    }
}

启动SpringBoot后,访问对应的方法,控制台也报错,但是表中是有一条数据的(原本是空表)。

这里写图片描述

查了查资料说的是在设计表的时候要选取的InnoDB引擎

回头看我的表引擎:

还真的是。。。。。。

解决

将数据表的引擎设置为InnoDB引擎。 然后再次执行,@Transitional注解才起了作用,数据表中没有了数据。

这里写图片描述

SpringBoot 使用Transaction注解遇到的坑

一、场景

开发一个多批次入库的功能,功能中涉及到多个表间的操作,对数据库表的操作要么同时成功,要么同时失败,不然就会存在脏数据,所以使用到了事务这个知识点()。

划重点:重要的都使用红色标出来了,大家如果不想看我废话,直接跳到红色字体即可0...0

二、Spring中使用的使用方式

1、使用传统的手动开始,手动提交事务即:beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。

2、使用Transaction注解的声明式事务,将事务的开启和提交交给Spring容器完成,这个也是本次我使用的方式,简单,但是使用时需要注意很多细节。

3、基于Spring AOP的切面的事务配置(本人很少使用这个,所以本文不重点刨析该知识点,想了解的可以到其他博客进行查看)

三、使用中遇到的问题

1、使用Transaction注解时抛出异常但是事务不起作用,异常时事务没有进行回滚?

答:经过排查,查询在开启事务的方法中最外层使用了try...catch进行了异常的捕获,因此抛出的异常本捕获了,切面无法捕获到异常,所以不会进行回滚。

解决:

(1) 手动指定切面捕获的异常类型(因为默认情况下只会在RuntimeExceptionimeException情况下才会进行事务的回滚),方式:@Transaction(rollbcackFor=Exception.class)

(2) 在catch中手动抛出一个运行时异常即:throw new RuntimeException();

(3) 如果需要在事务回滚时,给调用当前方法的调用者返回错误信息的话,用第二种方案就是不行的,因为抛出异常后的语句时不会执行的,包括return后面的语句,所以,此时可以手动进行事务回滚的语句调用即:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

2、刚插入的数据,无法马上查询到?

答: 这个问题是个大坑,整整苦恼了我两天(可能是之前使用事务相关的知识比较少,所以遇到了根本就不知道是什么原因),因为项目中使用的是MybatisPlus框架,一开始便怀疑是框架的缓存问题,因为刚插入马上查询时,查询的SQL语句并没有执行,即根本没到数据库去查,但是,手动关闭了缓存之后并没起效果,最后大佬看了代码后,一眼就指出问题所在(现在不得不感慨,经验时多么重要)。

要解决这个问题,首先要知道使用Transaction是怎么进行事务增强的,说白了,是通过生成代理对象进行切面注入的,当前对象并没有增强的作用,刚开始我插入和查询的方法都是写在一个service中,然后使用this调用这些方法,而this表示的是当前的service对象,所以这些方法根本就不在当前的事务中,因为刚插入的数据无法马上查询到0....0(我踩的大坑希望大家不要再踩了,太难受了..)

解决方法:说了这么多废话,现在知道问题产生的原因,所以就好解决了:

(1) 将所有的数据库操作方法抽取到另外一个Service对象中,然后通过@Autowire注入调用即可。

(2) 自己注入自己的对象即当前Service为A,可以直接使用:@Autowire private A a; 然后通过a调用相关数据库操作的方法(注意不要使用this,使用this的话无效),@Autowire private A a这句话实际上返回的是当前Service的代理对象,但特别需要注意的是:所有操作数据库相关的方法,访问权限都需改成public,不然会出现mapper和service注入为null---这个是个大坑,具体原因还不知道(这个方式推荐使用)

(3) 使用:((A) AopContext.currentProxy()).方法名()进行调用(听说这个方式在打包发布的时候会出现问题,本次没有试过这个方式,所以不推荐)

总结:

经验就是一个积累的过程,没有谁能够一步登天,所以脚踏实地才是成功的秘诀。本文只是本人在使用事务知识是遇到的问题的总结,希望能给大家一个参考,也希望大家多多支持猪先飞!

[!--infotagslink--]

相关文章

  • 解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题

    这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28
  • Swagger中@ApiIgnore注解的使用详解

    这篇文章主要介绍了Swagger中@ApiIgnore注解的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-21
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • 校验非空的注解@NotNull如何取得自定义的message

    这篇文章主要介绍了校验非空的注解@NotNull如何取得自定义的message,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-29
  • 详解springBoot启动时找不到或无法加载主类解决办法

    这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • 解决Springboot get请求是参数过长的情况

    这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
  • Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
  • Spring为什么不推荐使用@Autowired注解详析

    @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
  • Spring Boot项目@RestController使用重定向redirect方式

    这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • springBoot 项目排除数据库启动方式

    这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
  • Java中lombok的@Builder注解的解析与简单使用详解

    这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06
  • springboot中使用@Transactional注解事物不生效的坑

    这篇文章主要介绍了springboot中使用@Transactional注解事物不生效的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26
  • 处理@PathVariable注解允许参数为空、允许不传参数的问题

    这篇文章主要介绍了处理@PathVariable注解允许参数为空、允许不传参数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-23
  • 详解SpringBoot之访问静态资源(webapp...)

    这篇文章主要介绍了详解SpringBoot之访问静态资源(webapp...),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-14
  • SpringBoot接口接收json参数解析

    这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
  • Mybatis用注解写in查询的实现

    这篇文章主要介绍了Mybatis用注解写in查询的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-13
  • 解决@Transactional注解事务不回滚不起作用的问题

    这篇文章主要介绍了解决@Transactional注解事务不回滚不起作用的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-23
  • springboot多模块包扫描问题的解决方法

    这篇文章主要介绍了springboot多模块包扫描问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
  • Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用详解

    这篇文章主要介绍了Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-11-18