mybatis之事務管理

語言: CN / TW / HK

本篇來聊聊mybatis的事務管理機制,基於mybatis 3.4.6、mybatis-spring 1.3.2。

知識點

  • 什麼是事務
  • mybatis支援的事務管理方式
  • mybatis事務管理實現機制
  • spring是如何整合的

什麼是事務

學過sql的肯定都知道這個概念,事務在sql中是非常重要的概念。這裡做一個簡單的介紹。

事務( Transaction)由一次或者多次基本操作構成,或者說,事務由一條或者多條 SQL 語句構成,事務中的所有操作是一個整體,要麼全部執行成功,要麼全部執行失敗。它有4個基本的特性,分別是原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、永續性(Durability),簡稱 ACID

1) 原子性

一個事務中的所有 SQL 語句,要麼全部執行成功,要麼全部執行失敗,不會結束在中間的某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

2) 一致性

在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,其中包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。

3) 隔離性

資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。

4) 永續性

事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。

mybatis支援的事務管理方式

mybatis目前支援兩種方式管理事務

  • 原生jdbc
  • 容器託管

先介紹一下原生jdbc,原生jdbc就是我們直接在mybatis的配置檔案中配置對應的資料庫資訊,對應的事務相關操作都由mybatis內建的JdbcTransaction來完成,相當於是不依賴於任何容器的,配置方式官網也提到了

image.png

這裡的 type 填 JDBC 就可以了,需要注意的是如果要用原生 jdbc 方式的,必須通過配置檔案來實現,不支援 spring 的配置方式。再說一下容器託管方式。顧名思義就是將事務操作託管給具體的容器來實現。容器是什麼意思?簡單的理解,我們可以認為就是類似於spring這種存在,結合起來就是mybatis將事務的管理實現交給spring來實現,它有一個好處就是可以和容器共用一個數據庫連線,不用兩邊來各自管理,spring對於mybatis的整合就是自己實現了一個專門的容器託管類來做的。

mybatis事務管理實現機制

mybatis 的事務管理實現比較簡單,都在這一塊了

image.png

這裡用到了工廠模式來實現,對於原生的jdbc方式,通過JdbcTransaction來管理

image.png

可以看到這裡直接用了資料庫連線的提交和回滾操作。 你可能認為託管的實現就是ManagedTransaction,其實並不是。那為什麼有這個類,我猜想這裡只是提供了樣例般的程式碼,實際估計也是為了相容mybatis的不同配置。可以看到它並沒有做任何事情

image.png

對於TransactionFactory,它是依附於Environment中的,mybatis 都是通過Environment來獲取對應的TransactionFactory,然後再建立相應的Transaction。這也是為什麼我們可以配置不同環境來配置不同資料庫資訊來做到環境隔離。

image.png

而對於Transaction,它是依附於Executor的,也就是執行器,這個設計也非常容易理解,因為執行器本身就是對資料庫做增刪改查操作的,事務也放到裡面一起管理非常合理。

image.png

spring是如何整合的

通過上面的內容,我們知道 mybatis 支援事務管理託管給容器處理,而 spring 就是這種方式非常經典實現。因為我們目前用的大多是 spring 框架,所以我們在專案中用 mybatis 的時候都會引入mybatis-spring這個 jar 包,這個包就是 spring 整合 mybatis 的關鍵所在,裡面涉及內容也有不少,但這裡只分析事務管理這一塊。 對於mybatis的整合,這裡有個很關鍵的類SqlSessionFactoryBean

image.png

可以看到這是一個FactoryBean,就是通過它來獲取SqlSessionFactory的,直接看核心邏輯org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory

image.png

可以看到這裡建立了spring實現的事務管理類SpringManagedTransactionFactory,然後建立了一個Environment設定到Configuration中,這樣後續 mybatis 在獲取事務的時候獲取到的都是SpringManagedTransactionFactory

image.png

所有實現都在這個包下面,結構是不是很熟悉,就是基於 mybatis 的工廠模式那一套。

總結

mybatis的事務管理實現還是相對比較簡單的,其實我們平時自己去配置具體的事務管理類也很少,因為如果用的spring,基本不用再自己做什麼處理了,但是這個設計還是不錯的,直接把相關模組交給容器處理,容器接入也簡單。

「其他文章」