springboot使用mybatis開啟事務回滾
1.前言
以前沒有使用mybatis,可以關閉自動提交,然后做sql操作,對操作進行catch捕獲異常,
如果沒有異常則commit 提交 ,有異常則 rollback 回滾,新增的數(shù)據(jù)則刪除 ,修改的數(shù)據(jù)則修改回去,刪除的則新增,
這就是事務操作。
事務有四大特性
(1)原子性:要么全部執(zhí)行成功,要么不執(zhí)行。
(2)一致性:事務執(zhí)行的結(jié)果,必須使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài)。
(3)隔離性:并發(fā)操作同一個表時數(shù)據(jù)庫會開啟多個事務,多個事務之間相互隔離。
(4)持久性:當事務確認完成后,對數(shù)據(jù)的改變是永久性的。
那么mybatis怎么具體開啟事務?
spring boot 開啟其實很簡單,使用注解開啟即可,但是需要注意,需要觸發(fā)非檢查異常才會做事務回滾操作,【Exception 是檢查異?!?/p>
但是如果使用try catch 捕獲異常,也不會觸發(fā)異常,因為異常被 吃下去了,做了服務降級操作,事務以為沒有異常發(fā)生,因此不會觸發(fā)回滾操作。
如果非要觸發(fā)事務回滾,則需要在事務注解指定會觸發(fā)事務回滾操作的異常類型,如果需要自定義拋出異常后反饋前端的數(shù)據(jù),那么需要自定義異常,
自定義異常將會在下一隨筆詳細講解。
經(jīng)過測試總結(jié):
(1)父級方法開啟事務 @Transactional,父級發(fā)生異常,不僅父級會回滾,他調(diào)用的所有子方法都會回滾,也就是說,回滾事務父級可以影響所有子級.
(2)如果子級開了事務,父級沒有開,發(fā)生異常,則僅僅讓子級方法回滾,如果父級也開了事務,那么所有的子級將會和父級一起回滾。
2.操作
(1)提前配置好spring boot + mybatis
目錄結(jié)構(gòu)

紅色箭頭的文件是必要的,
(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 數(shù)據(jù)源 依賴包-->
<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)此時的數(shù)據(jù)庫表信息

3.測試
(1)父級方法不開啟事務,子級開啟,讓子級方法觸發(fā)異常


啟動后訪問http://localhost:1004/sw

返回了500錯誤
報了個異常

查看數(shù)據(jù)庫表信息

可見父級方法并沒有回滾,子級方法事務回滾了
(2)恢復數(shù)據(jù)庫表信息
父級方法不開啟事務,子級開啟,讓子級方法catch捕獲觸發(fā)異常
父級方法不變,修改子級方法

啟動后訪問http://localhost:1004/sw

控制臺打印

查看數(shù)據(jù)庫

兩次sql操作都執(zhí)行了,子方法觸發(fā)了異常,并沒有做事務回滾操作,因為catch將服務降級了
那怎么辦?
希望既可以做事務回滾操作,又能讓前端獲取指定的反饋信息怎么操作?
答案是手動拋出異常
throw new RuntimerException("這里寫上你需要的騷話");
(3)恢復數(shù)據(jù)庫表信息
父級方法不開啟事務,子級開啟,讓子級方法catch捕獲觸發(fā)異常后,手動拋出異常
父級方法不變,修改子級方法

啟動后訪問http://localhost:1004/sw

控制臺打印

查看數(shù)據(jù)庫

可見,子級方法事務回滾了,但是父級沒有,因為父級沒有開啟事務。
(4)如果使用 throw new Exception() 拋出異常則無法觸發(fā)事務回滾

恢復數(shù)據(jù)庫后,啟動工程,訪問http://localhost:1004/sw

查看數(shù)據(jù)庫

可見,不能使用throw new Exception()
(5)恢復數(shù)據(jù)庫
在事務注解指定拋出的異常則可以讓檢查性異常觸發(fā)事務

父級方法不變,修改子級方法
啟動工程,訪問http://localhost:1004/sw

查看數(shù)據(jù)庫

顯然 ,子級方法做了事務回滾操作了,父級沒影響
(6)好了這里開始需要修改父級啦,
在父級添加事務注解

子級方法不變

啟動工程,訪問http://localhost:1004/sw

查看數(shù)據(jù)庫

顯然,子級拋出異常,做了事務回滾操作,父級也做了事務回滾操作
(7)恢復數(shù)據(jù)庫,刪除子級方法事務注解,即關閉子級事務,父即開啟事務

啟動工程,訪問http://localhost:1004/sw

查看數(shù)據(jù)庫

顯然,子級拋出異常,做了事務回滾操作,父級也做了事務回滾操作,即便子級沒有開啟事務,只有父級開啟,
因此可見,只要父級開啟了事務,不論是子級還是父級觸發(fā)了非檢查異常都會做事務回滾,如果是檢查異常,則需要在事務注解指定異常類型。
(8)如果子級方法不觸發(fā)異常,而是在父級觸發(fā),那么子級方法是否會回滾?
答案是會的
修改父級方法

修改子級方法

啟動工程,訪問http://localhost:1004/sw

查看數(shù)據(jù)庫

顯然,父級開啟了事務且拋出異常,做了回滾操作,子級沒有開啟事務也沒有拋出異常,仍然做了事務回滾操作
到此這篇關于springboot使用mybatis開啟事務回滾的文章就介紹到這了,更多相關springboot mybatis 事務回滾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Java使用Jsch與sftp服務器實現(xiàn)ssh免密登錄
這篇文章主要介紹了詳解Java使用Jsch與sftp服務器實現(xiàn)ssh免密登錄,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10
Spring Boot Admin監(jiān)控服務如何使用
這篇文章主要介紹了Spring Boot Admin監(jiān)控服務如何使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
Java中jdk1.8和jdk17相互切換實戰(zhàn)步驟
之前做Java項目時一直用的是jdk1.8,現(xiàn)在想下載另一個jdk版本17,并且在之后的使用中可以進行相互切換,下面這篇文章主要給大家介紹了關于Java中jdk1.8和jdk17相互切換的相關資料,需要的朋友可以參考下2023-05-05

