软件编程
位置:首页>> 软件编程>> java编程>> springboot使用mybatis开启事务回滚

springboot使用mybatis开启事务回滚

作者:岑惜  发布时间:2022-09-10 05:15:55 

标签:springboot,mybatis,事务回滚

1.前言

以前没有使用mybatis,可以关闭自动提交,然后做sql操作,对操作进行catch捕获异常,

如果没有异常则commit 提交 ,有异常则 rollback 回滚,新增的数据则删除 ,修改的数据则修改回去,删除的则新增,

这就是事务操作。

事务有四大特性

(1)原子性:要么全部执行成功,要么不执行。

(2)一致性:事务执行的结果,必须使数据库从一个一致性状态变到另一个一致性状态。

(3)隔离性:并发操作同一个表时数据库会开启多个事务,多个事务之间相互隔离。

(4)持久性:当事务确认完成后,对数据的改变是永久性的。

那么mybatis怎么具体开启事务?

spring boot 开启其实很简单,使用注解开启即可,但是需要注意,需要触发非检查异常才会做事务回滚操作,【Exception 是检查异常】

但是如果使用try catch 捕获异常,也不会触发异常,因为异常被 吃下去了,做了服务降级操作,事务以为没有异常发生,因此不会触发回滚操作。

如果非要触发事务回滚,则需要在事务注解指定会触发事务回滚操作的异常类型,如果需要自定义抛出异常后反馈前端的数据,那么需要自定义异常,

自定义异常将会在下一随笔详细讲解。

经过测试总结:

(1)父级方法开启事务 @Transactional,父级发生异常,不仅父级会回滚,他调用的所有子方法都会回滚,也就是说,回滚事务父级可以影响所有子级.

(2)如果子级开了事务,父级没有开,发生异常,则仅仅让子级方法回滚,如果父级也开了事务,那么所有的子级将会和父级一起回滚。

2.操作

(1)提前配置好spring boot + mybatis

目录结构

springboot使用mybatis开启事务回滚

红色箭头的文件是必要的,

(2)导入依赖包

springboot使用mybatis开启事务回滚

完整源码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>cen.cloud</groupId>
       <artifactId>cen-mycloud</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.example</groupId>
   <artifactId>rabbitmq-producer-1004</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>rabbitmq-producer-1004</name>
   <description>Demo project for Spring Boot</description>

<properties>
       <java.version>1.8</java.version>
   </properties>

<dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

<dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
           <exclusions>
               <exclusion>
                   <groupId>org.junit.vintage</groupId>
                   <artifactId>junit-vintage-engine</artifactId>
               </exclusion>
           </exclusions>
       </dependency>

<!--eureka 注册中心依赖包 -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
       </dependency>

<!-- 消息中间件-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-amqp</artifactId>
           <version>2.1.6.RELEASE</version>
       </dependency>

<!-- MySQL 依赖-->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <!--            <scope>runtime</scope>-->
           <version>5.1.30</version>
       </dependency>
       <!--MySQL 数据源 依赖包-->
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid-spring-boot-starter</artifactId>
           <version>1.1.10</version>
       </dependency>

<!--        mybatis依赖-->
       <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>2.1.2</version>
       </dependency>
       <!-- mybatis的逆向工程依赖包-->
       <dependency>
           <groupId>org.mybatis.generator</groupId>
           <artifactId>mybatis-generator-core</artifactId>
           <version>1.3.2</version>
       </dependency>

</dependencies>

<build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

</project>

(3)启动类开启事务管理

springboot使用mybatis开启事务回滚

(4)此时的数据库表信息

springboot使用mybatis开启事务回滚

3.测试

(1)父级方法不开启事务,子级开启,让子级方法触发异常

springboot使用mybatis开启事务回滚

springboot使用mybatis开启事务回滚

启动后访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

返回了500错误

报了个异常

springboot使用mybatis开启事务回滚

查看数据库表信息

springboot使用mybatis开启事务回滚

可见父级方法并没有回滚,子级方法事务回滚了

(2)恢复数据库表信息

父级方法不开启事务,子级开启,让子级方法catch捕获触发异常

父级方法不变,修改子级方法

springboot使用mybatis开启事务回滚

启动后访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

控制台打印

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

两次sql操作都执行了,子方法触发了异常,并没有做事务回滚操作,因为catch将服务降级了

那怎么办?

希望既可以做事务回滚操作,又能让前端获取指定的反馈信息怎么操作?

答案是手动抛出异常

throw new RuntimerException("这里写上你需要的骚话");

(3)恢复数据库表信息

父级方法不开启事务,子级开启,让子级方法catch捕获触发异常后,手动抛出异常

父级方法不变,修改子级方法

springboot使用mybatis开启事务回滚

启动后访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

控制台打印

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

可见,子级方法事务回滚了,但是父级没有,因为父级没有开启事务。

(4)如果使用 throw new Exception() 抛出异常则无法触发事务回滚

springboot使用mybatis开启事务回滚

恢复数据库后,启动工程,访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

可见,不能使用throw new Exception()

(5)恢复数据库

在事务注解指定抛出的异常则可以让检查性异常触发事务

springboot使用mybatis开启事务回滚

父级方法不变,修改子级方法

启动工程,访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

显然 ,子级方法做了事务回滚操作了,父级没影响

(6)好了这里开始需要修改父级啦,

在父级添加事务注解

springboot使用mybatis开启事务回滚

子级方法不变

springboot使用mybatis开启事务回滚

启动工程,访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

显然,子级抛出异常,做了事务回滚操作,父级也做了事务回滚操作

(7)恢复数据库,删除子级方法事务注解,即关闭子级事务,父即开启事务

springboot使用mybatis开启事务回滚

启动工程,访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

显然,子级抛出异常,做了事务回滚操作,父级也做了事务回滚操作,即便子级没有开启事务,只有父级开启,

因此可见,只要父级开启了事务,不论是子级还是父级触发了非检查异常都会做事务回滚,如果是检查异常,则需要在事务注解指定异常类型。

(8)如果子级方法不触发异常,而是在父级触发,那么子级方法是否会回滚?

答案是会的

修改父级方法

springboot使用mybatis开启事务回滚

修改子级方法

springboot使用mybatis开启事务回滚

启动工程,访问http://localhost:1004/sw

springboot使用mybatis开启事务回滚

查看数据库

springboot使用mybatis开启事务回滚

显然,父级开启了事务且抛出异常,做了回滚操作,子级没有开启事务也没有抛出异常,仍然做了事务回滚操作

来源:https://www.cnblogs.com/c2g5201314/p/13163097.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com