欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文搞懂?MyBatis的事務(wù)管理機(jī)制

 更新時(shí)間:2023年05月12日 08:35:03   作者:Cosolar  
MyBatis是一款優(yōu)秀的持久層框架,相信很多Java后端開發(fā)人員對(duì)它都不會(huì)陌生。本文將從事務(wù)概述、MyBatis實(shí)現(xiàn)事務(wù)的方式、事務(wù)實(shí)現(xiàn)源碼分析方面詳細(xì)解析MyBatis的事務(wù)管理機(jī)制,需要的朋友可以參考下

一、事務(wù)概述

事務(wù)是指要么全部執(zhí)行成功,要么全部回滾的一組操作。在數(shù)據(jù)庫中,一般使用 ACID 規(guī)則來約束事務(wù),即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)。在 MyBatis 中,也遵循了這一規(guī)則。

MyBatis中的事務(wù)是指一系列數(shù)據(jù)庫操作,這些操作要么全部執(zhí)行成功,要么全部執(zhí)行失敗。如果操作過程中發(fā)生錯(cuò)誤,所有對(duì)數(shù)據(jù)庫的修改都將被回滾,即還原到最初狀態(tài)。事務(wù)是確保數(shù)據(jù)一致性和完整性的關(guān)鍵機(jī)制之一。

在MyBatis中,我們可以通過三種方式來管理事務(wù):

  • 編程式管理事務(wù):在代碼中顯式開啟、提交或回滾事務(wù)。

  • 聲明式管理事務(wù):通過AOP代理實(shí)現(xiàn)事務(wù)管理,可以讓代碼更簡潔,更容易維護(hù)。

  • 注解式管理事務(wù):通過注解方式管理事務(wù),是聲明式管理事務(wù)的一種擴(kuò)展方式。

以上三種方式,最常用的是聲明式管理事務(wù),它可以將事務(wù)管理和業(yè)務(wù)邏輯分離,降低代碼的耦合度,提高代碼的可讀性和可維護(hù)性。在MyBatis中,聲明式事務(wù)管理需要借助Spring框架來實(shí)現(xiàn)。

在使用聲明式事務(wù)管理時(shí),我們需要在Spring配置文件中配置TransactionManager和TransactionProxyFactoryBean兩個(gè)bean,其中TransactionManager負(fù)責(zé)事務(wù)管理,TransactionProxyFactoryBean負(fù)責(zé)AOP代理。

下面是一個(gè)示例:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.example.UserMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

<bean id="userMapperProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="userMapper" />
    <property name="transactionAttributes">
        <props>
            <prop key="select*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="insert*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

在編寫完上述配置后,我們就可以對(duì)UserMapper接口中的方法進(jìn)行事務(wù)管理了。例如,在UserService類中,我們可以注入userMapperProxy,并調(diào)用其中的方法:

@Service
public class UserService {

    @Autowired
    UserMapper userMapperProxy;

    @Transactional
    public void addUser(User user) {
        userMapperProxy.addUser(user);
    }
}

在代碼中,通過@Transactional注解聲明了該方法需要進(jìn)行事務(wù)管理,當(dāng)方法執(zhí)行過程中發(fā)生異常時(shí),事務(wù)將會(huì)回滾。

MyBatis支持多種事務(wù)管理方式,但是建議使用聲明式事務(wù)管理,因?yàn)樗軌蜃畲蟪潭鹊亟档痛a的耦合度,并提高代碼的可讀性和可維護(hù)性。

二、MyBatis 實(shí)現(xiàn)事務(wù)的方式

MyBatis 實(shí)現(xiàn)事務(wù)也有多種方式,其中最常用的方式有兩種:編程式事務(wù)和聲明式事務(wù)。接下來我們將分別來介紹這兩種方式。

1. 編程式事務(wù)

編程式事務(wù)就是通過編寫代碼來手動(dòng)管理事務(wù),主要包括以下幾個(gè)步驟:

1)獲取 SqlSession 對(duì)象;

2)設(shè)置自動(dòng)提交為 false;

3)執(zhí)行數(shù)據(jù)庫操作;

4)提交事務(wù);

5)關(guān)閉 SqlSession。

代碼示例如下:

SqlSession sqlSession = sqlSessionFactory.openSession(false);
try {
    // 執(zhí)行數(shù)據(jù)庫操作
    sqlSession.insert("insertUser", user);
    sqlSession.update("updateUser", user);
    
    // 提交事務(wù)
    sqlSession.commit();
} catch (Exception e) {
    // 回滾事務(wù)
    sqlSession.rollback();
} finally {
    // 關(guān)閉 SqlSession
    sqlSession.close();
}

以上代碼中,通過設(shè)置自動(dòng)提交為 false 來關(guān)閉自動(dòng)提交事務(wù)的方式,然后在 try 塊中執(zhí)行需要進(jìn)行事務(wù)管理的數(shù)據(jù)庫操作,如果出現(xiàn)異常則回滾事務(wù),否則提交事務(wù),并在 finally 中關(guān)閉 SqlSession。

2. 聲明式事務(wù)

聲明式事務(wù)就是在配置文件中通過事務(wù)管理器來管理事務(wù),這種方式更加靈活和方便,我們只需要在配置文件中配置好即可。MyBatis 內(nèi)置了兩個(gè)事務(wù)管理器:JDBC 和 Spring。

(1)JDBC 事務(wù)管理器

JDBC 事務(wù)管理器是 MyBatis 內(nèi)置的一個(gè)事務(wù)管理器,在 SqlSessionFactory 的配置文件中進(jìn)行配置:

<transactionManager type="JDBC" />

(2)Spring 事務(wù)管理器

Spring 事務(wù)管理器是基于 Spring 框架的事務(wù)管理器,需要引入 Spring 的包,并在 MyBatis 的配置文件中配置:

<transactionManager type="SPRING" />

在使用 Spring 事務(wù)管理器時(shí),還需要在 Spring 的配置文件中配置事務(wù)管理器和數(shù)據(jù)源,具體可以參考 Spring 的文檔。

三、事務(wù)源碼理解

(1)TransactionFactory

在 MyBatis 中,事務(wù)工廠需要實(shí)現(xiàn) org.apache.ibatis.transaction.TransactionFactory 接口,該接口有一個(gè)方法:

Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);

該方法用于創(chuàng)建一個(gè)新的 Transaction 實(shí)例。

例如,如果你要使用 JDBC 來管理事務(wù),可以使用默認(rèn)提供的 JdbcTransactionFactory 類來創(chuàng)建事務(wù)工廠。以下是一個(gè)創(chuàng)建事務(wù)工廠的示例代碼:

import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;

public class MyTransactionFactory {
    public static TransactionFactory createTransactionFactory() {
        return new JdbcTransactionFactory();
    }
}

以上代碼中,我們使用 JdbcTransactionFactory 創(chuàng)建一個(gè)新的事務(wù)工廠。實(shí)際上,在 MyBatis 的配置文件中,可以直接引用這個(gè)工廠。

例如:

<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <!-- 數(shù)據(jù)源配置 -->
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <!-- Mapper 配置 -->
</configuration>

以上代碼中,我們使用了 <transactionManager type="JDBC"/> 來配置事務(wù)管理器的類型,并且在 <dataSource> 標(biāo)簽中指定了數(shù)據(jù)源的類型為 POOLED,也就是一個(gè)連接池?cái)?shù)據(jù)源。

在實(shí)際應(yīng)用中,還可以通過自定義事務(wù)工廠來創(chuàng)建其他類型的事務(wù)。例如,如果你要使用 Atomikos 來管理事務(wù),可以自定義一個(gè) AtomikosTransactionFactory 類來創(chuàng)建事務(wù)工廠。

(2)JdbcTransaction

在 MyBatis 中,Transaction 接口的默認(rèn)實(shí)現(xiàn)是 JdbcTransaction 類。這個(gè)類的創(chuàng)建是在 JdbcTransactionFactory 工廠類中完成的。

以下是 JdbcTransactionFactory 工廠類中用于創(chuàng)建 Transaction 實(shí)例的代碼:

@Override
public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
  return new JdbcTransaction(dataSource, level, autoCommit);
}

在這段代碼中,我們可以看到工廠方法 newTransaction() 的實(shí)現(xiàn)。該方法接收三個(gè)參數(shù):數(shù)據(jù)源、事務(wù)隔離級(jí)別和是否自動(dòng)提交。

newTransaction 方法中,我們使用這些參數(shù)創(chuàng)建一個(gè)新的 JdbcTransaction 實(shí)例,并將其返回。JdbcTransaction 類中實(shí)現(xiàn)了 Transaction 接口,因此可以直接返回。

以下是 JdbcTransaction 類的主要源碼:

public class JdbcTransaction implements Transaction {

  protected Connection connection;
  protected DataSource dataSource;
  protected TransactionIsolationLevel level;
  protected boolean autoCommit;

  public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) throws SQLException {
    dataSource = ds;
    level = desiredLevel;
    autoCommit = desiredAutoCommit;
    openConnection();
    setDesiredAutoCommit();
    setDesiredTransactionIsolation();
  }

  // ...其他方法

}

JdbcTransaction 類中,我們創(chuàng)建了一個(gè)基本的事務(wù)對(duì)象,它包含了一些屬性,例如事務(wù)管理器、連接、事務(wù)隔離級(jí)別等等。在構(gòu)造函數(shù)中,我們使用傳入的參數(shù)來初始化這些屬性值。

除了構(gòu)造函數(shù)之外,還有一些其他的方法用于對(duì)事務(wù)進(jìn)行操作,例如提交、回滾、關(guān)閉等。這些方法都是從 Transaction 接口中繼承來的。

因此,在 MyBatis 中,創(chuàng)建一個(gè)新的事務(wù)就是通過事務(wù)工廠和相應(yīng)的創(chuàng)建方法來創(chuàng)建一個(gè)特定類型的事務(wù)對(duì)象。而在事務(wù)對(duì)象中,我們可以對(duì)事務(wù)進(jìn)行各種操作。

(3)ManagedTransaction

在 MyBatis 中,除了 JdbcTransaction 之外,還提供了另外一種稱為 ManagedTransaction 的事務(wù)實(shí)現(xiàn),它是一種由容器或框架來管理的事務(wù),而不是 MyBatis 內(nèi)部來管理。

ManagedTransaction 接口的默認(rèn)實(shí)現(xiàn)是 SpringManagedTransaction 類。該類實(shí)現(xiàn)了 MyBatis 的 Transaction 接口,但其本身并不處理任何事務(wù)邏輯,而是委托給 Spring 框架進(jìn)行處理。

以下是 SpringManagedTransaction 類的主要源碼:

public class SpringManagedTransaction implements Transaction {

  private final DataSource dataSource;
  private Connection connection;
  private boolean isConnectionTransactional;
  private boolean autoCommit;

  public SpringManagedTransaction(DataSource dataSource) {
    this.dataSource = dataSource;
  }

  @Override
  public Connection getConnection() throws SQLException {
    if (this.connection == null) {
      openConnection();
    }
    return this.connection;
  }

  // ...其他方法

}

SpringManagedTransaction 類中,我們使用傳入的數(shù)據(jù)源來創(chuàng)建一個(gè)新的事務(wù)對(duì)象。在 getConnection() 方法中,如果當(dāng)前連接不存在,則會(huì)打開一個(gè)新的連接并返回;否則直接返回已經(jīng)存在的連接。

需要注意的是,SpringManagedTransaction 并不自行管理事務(wù),而是將事務(wù)管理工作交給了 Spring 框架。因此,如果要使用 SpringManagedTransaction,我們需要在 Spring 配置文件中配置相應(yīng)的事務(wù)管理器,例如 DataSourceTransactionManagerJpaTransactionManager 等。

總之,相比于 JdbcTransaction,ManagedTransaction 更適合在容器或框架中使用,而不是在 MyBatis 內(nèi)部使用。如果你使用 Spring 或其他類似的框架來管理事務(wù),則可以考慮使用 ManagedTransaction 來實(shí)現(xiàn) MyBatis 的事務(wù)管理。

四、測試用例

接下來我們將通過一個(gè)示例來詳細(xì)介紹 MyBatis 的事務(wù)管理機(jī)制。假設(shè)我們需要執(zhí)行一個(gè)復(fù)雜的業(yè)務(wù)操作,需要同時(shí)更新多個(gè)表,我們就可以使用編程式事務(wù)來管理事務(wù)。

在 Mapper.xml 文件中,編寫如下 SQL 語句:

<insert id="insertUser" parameterType="com.example.User">
    insert into user (id, name, age) values (#{id}, #{name}, #{age})
</insert>

<update id="updateAccount" parameterType="com.example.Account">
    update account set balance = #{balance} where id = #{id}
</update>

然后我們編寫一個(gè) Service 類來調(diào)用 Mapper 文件中的方法,代碼如下:

public class UserService {
    private SqlSessionFactory sqlSessionFactory;

    public UserService(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    public void addUserAndAccount(User user, Account account) {
        SqlSession sqlSession = sqlSessionFactory.openSession(false);
        try {
            // 執(zhí)行數(shù)據(jù)庫操作
            sqlSession.insert("insertUser", user);
            sqlSession.update("updateAccount", account);
            
            // 提交事務(wù)
            sqlSession.commit();
        } catch (Exception e) {
            // 回滾事務(wù)
            sqlSession.rollback();
        } finally {
            // 關(guān)閉 SqlSession
            sqlSession.close();
        }
    }
}

以上代碼中,我們通過 openSession(false) 來獲取 SqlSession 對(duì)象,并設(shè)置自動(dòng)提交為 false,然后在 try 塊中執(zhí)行數(shù)據(jù)庫操作,如果出現(xiàn)異常則回滾事務(wù),否則提交事務(wù),并在 finally 中關(guān)閉 SqlSession。在實(shí)際開發(fā)中,我們可以將 SqlSession 放入 Spring 管理中,這樣就更加方便了。

以上就是一文搞懂 MyBatis的事務(wù)管理機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于MyBatis 事務(wù)管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • idea在用Mybatis時(shí)xml文件sql不提示解決辦法(提示后背景顏色去除)

    idea在用Mybatis時(shí)xml文件sql不提示解決辦法(提示后背景顏色去除)

    mybatis的xml文件配置的時(shí)候,有時(shí)候會(huì)沒有提示,這讓我們很頭疼,下面這篇文章主要給大家介紹了關(guān)于idea在用Mybatis時(shí)xml文件sql不提示的解決辦法,提示后背景顏色去除的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • java字節(jié)碼框架ASM的深入學(xué)習(xí)

    java字節(jié)碼框架ASM的深入學(xué)習(xí)

    這篇文章主要給大家介紹了java中字節(jié)碼框架ASM的相關(guān)資料,文中介紹的非常詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • Spring整合CXF webservice restful實(shí)例詳解

    Spring整合CXF webservice restful實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了Spring整合CXF webservice restful的實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 如何在Java中使用WebSocket協(xié)議

    如何在Java中使用WebSocket協(xié)議

    WebSocket是一種基于 TCP 協(xié)議的全雙工通信協(xié)議,可以在瀏覽器和服務(wù)器之間建立實(shí)時(shí)、雙向的數(shù)據(jù)通信,下面這篇文章主要給大家介紹了關(guān)于如何在Java中使用WebSocket協(xié)議的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • java實(shí)現(xiàn)讀取、刪除文件夾下的文件

    java實(shí)現(xiàn)讀取、刪除文件夾下的文件

    本文給大家分享的是java實(shí)現(xiàn)讀取、刪除文件夾下的文件,其中File.delete()用于刪除“某個(gè)文件或者空目錄”!所以要?jiǎng)h除某個(gè)目錄及其中的所有文件和子目錄,要進(jìn)行遞歸刪除,有需要的小伙伴可以參考下。
    2015-05-05
  • SpringCloud 服務(wù)注冊和消費(fèi)實(shí)現(xiàn)過程

    SpringCloud 服務(wù)注冊和消費(fèi)實(shí)現(xiàn)過程

    這篇文章主要介紹了SpringCloud 服務(wù)注冊和消費(fèi)實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • java實(shí)現(xiàn)html轉(zhuǎn)pdf方法步驟

    java實(shí)現(xiàn)html轉(zhuǎn)pdf方法步驟

    這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)html轉(zhuǎn)pdf方法的相關(guān)資料,要將HTML轉(zhuǎn)換成PDF,我們需要借助Java中的第三方庫,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • Java常見基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

    Java常見基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

    這篇文章主要介紹了Java常見數(shù)據(jù)結(jié)構(gòu)面試題,帶有答案及解釋,希望對(duì)廣大的程序愛好者有所幫助,同時(shí)祝大家有一個(gè)好成績,需要的朋友可以參考下,希望可以幫助到你
    2021-07-07
  • JavaFx 實(shí)現(xiàn)按鈕防抖功能

    JavaFx 實(shí)現(xiàn)按鈕防抖功能

    最近Sun公司推出了JavaFX框架,使用它可以利用JavaFX編程語言來開發(fā)富互聯(lián)網(wǎng)應(yīng)用程序(RIA),這篇文章主要介紹了JavaFx 實(shí)現(xiàn)按鈕防抖功能,需要的朋友可以參考下
    2022-01-01
  • Spring?Cloud?Feign?使用對(duì)象參數(shù)的操作

    Spring?Cloud?Feign?使用對(duì)象參數(shù)的操作

    這篇文章主要介紹了Spring?Cloud?Feign?如何使用對(duì)象參數(shù)的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02

最新評(píng)論