首頁 > 軟體

springboot使用mybatis開啟事務回滾

2023-02-06 06:02:39

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

檢視資料庫

顯然,父級開啟了事務且丟擲異常,做了回滾操作,子級沒有開啟事務也沒有丟擲異常,仍然做了事務回滾操作

到此這篇關於springboot使用mybatis開啟事務回滾的文章就介紹到這了,更多相關springboot mybatis 事務回滾內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com