1.前言  

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

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

这就是事务操作。

  事务有四大特性

(1)原子性:要么全部执行成功,要么不执行。
(2)一致性:事务执行的结果,必须使数据库从一个一致性状态变到另一个一致性状态。
(3)隔离性:并发操作同一个表时数据库会开启多个事务,多个事务之间相互隔离。
(4)持久性:当事务确认完成后,对数据的改变是永久性的。

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

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

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

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

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

经过测试总结:

(1)父级方法开启事务 @Transactional,父级发生异常,不仅父级会回滚,他调用的所有子方法都会回滚,也就是说,回滚事务父级可以影响所有子级.
(2)如果子级开了事务,父级没有开,发生异常,则仅仅让子级方法回滚,如果父级也开了事务,那么所有的子级将会和父级一起回滚。

2.操作

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

目录结构

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

(2)导入依赖包

完整源码

<?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)启动类开启事务管理

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

3.测试

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

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

返回了500错误

报了个异常

查看数据库表信息

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

(2)恢复数据库表信息,

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

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

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

控制台打印

查看数据库

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

那怎么办?

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

答案是手动抛出异常

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

(3)恢复数据库表信息,

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

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

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

控制台打印

查看数据库

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

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

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

查看数据库

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

(5)恢复数据库,

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

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

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

查看数据库

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

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

在父级添加事务注解

子级方法不变

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

查看数据库

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

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

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

查看数据库

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

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

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

答案是会的

修改父级方法

修改子级方法

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

查看数据库

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

最新文章

  1. jQuery与ajax 基础运用
  2. Kernels
  3. Shiro 学习笔记(二)——shiro身份验证
  4. Mysql日志操作
  5. PayPal贝宝集成
  6. HTTP协议和几种常见的状态码
  7. 用DOM实现文章采集-HtmlAgilityPack实现html解析
  8. PHPCMS 插件开发教程及经验谈
  9. Android外部存储 - 官方文档解读
  10. 高性能的JavaScript--加载和执行[转]
  11. Ubuntu 12.04 (10) Personal Environment - @staticor
  12. Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class android.sup
  13. Python 官方文档解读(1):66 个内置函数
  14. java安装与配置
  15. AMQP close-reason, initiated by Peer, code=406
  16. ios-微信支付登录分享-notification通知
  17. JavaScript高级程序设计笔记(一)
  18. JavaScript中的内置对象-8--2.String-符串对象 方法; 截取方法; 综合应用; 其他方法;
  19. POJ:3083 Children of the Candy Corn(bfs+dfs)
  20. 网站换了HTTPS后残留部分http处理方式

热门文章

  1. 使用$.ajax方式实现页面异步访问,局部更新的效果
  2. arcgis api for js回调函数如何等待同步
  3. apt和apt-get的区别
  4. Android工具 - SQLITE3
  5. MySQL慢日志优化
  6. 使用.NET 6开发TodoList应用(2)——项目结构搭建
  7. LuoguP7019 [NWRRC2017]Auxiliary Project 题解
  8. ACwing1216. 饮料换购
  9. JAVA通过正则匹配html里面body标签的内容,去掉body标签
  10. 【LeetCode】344. Reverse String 解题报告(Java & Python)