MyBatis源码解析之Transaction事务模块

MyBatis源码解析之Transaction事务模块

一、概述

MyBatis是一款优秀的持久层框架,它支持事务控制,能够帮助开发者方便地管理数据的事务。MyBatis的事务管理模块主要由Transaction接口、TransactionFactory接口、TransactionIsolationLevel枚举和JdbcTransaction、ManagedTransaction两个类实现。

二、Transaction接口

Transaction接口定义了事务的基本方法,包括提交事务、回滚事务和关闭事务。一个SqlSessionFactory实例可以创建一个Transaction实例。

public interface Transaction {
    void commit() throws SQLException;

    void rollback() throws SQLException;

    void close() throws SQLException;

    Integer getTimeout() throws SQLException;
}

三、TransactionFactory接口

TransactionFactory接口定义了创建Transaction实例的方法。

public interface TransactionFactory {
    Transaction newTransaction(Connection conn);
    /**
     * @since 3.1.0
     */
    Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
    void setProperties(Properties props);
}

四、TransactionIsolationLevel枚举

TransactionIsolationLevel枚举定义了事务的隔离级别,包括NONE、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。

五、JdbcTransaction类

JdbcTransaction继承自BaseTransaction类,是基于JDBC实现的事务管理器。它的创建依赖于TransactionFactory实例。在JdbcTransaction对象创建的过程中,如果autoCommit为false,则将会开启事务。

示例代码:

public class JdbcTransaction extends BaseTransaction {

    public JdbcTransaction(Connection connection) {
        delegate = new JdbcTransactionImpl(connection);
    }

    public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
        Connection conn;
        try {
            conn = ds.getConnection();
            if (conn.getAutoCommit() != desiredAutoCommit) {
                conn.setAutoCommit(desiredAutoCommit);
            }
            delegate = new JdbcTransactionImpl(conn);
        } catch (SQLException e) {
            throw new TransactionException("Error initializing JDBC Connection.  Cause: " + e, e);
        }
    }

    private static class JdbcTransactionImpl extends BaseTransactionState implements TransactionState {
        private Connection connection;
        private TransactionIsolationLevel level;
        private boolean autoCommmit;

        public JdbcTransactionImpl(Connection connection) {
            this.connection = connection;
            try {
                this.level = TransactionIsolationLevel.fromValue(connection.getTransactionIsolation());
                this.autoCommmit = connection.getAutoCommit();
            } catch (SQLException e) {
                throw new TransactionException("Error configuring Transaction.  Cause: " + e, e);
            }
        }

        public void commit() throws SQLException {
            if (connection != null && !connection.isClosed()) {
                if (autoCommmit != connection.getAutoCommit()) {
                    connection.setAutoCommit(autoCommmit);
                }
                connection.commit();
            }
        }

        public void rollback() throws SQLException {
            if (connection != null && !connection.isClosed()) {
                if (autoCommmit != connection.getAutoCommit()) {
                    connection.setAutoCommit(autoCommmit);
                }
                connection.rollback();
            }
        }

        public void close() throws SQLException {
            connection.close();
        }

        public Integer getTimeout() throws SQLException {
            return null;
        }
    }

}

六、ManagedTransaction类

ManagedTransaction类也继承自BaseTransaction类,是基于容器环境下的事务管理器,它不会commit和rollback事务,而是依赖容器(如Spring)来完成这些操作。也就是说,它将交给上层容器来管理事务。

示例代码:

public class ManagedTransaction extends BaseTransaction {

    private Connection connection;
    private TransactionIsolationLevel level;
    private boolean closeConnection;

    public ManagedTransaction(Connection connection, boolean closeConnection) {
        this.connection = connection;
        this.closeConnection = closeConnection;
        this.delegate = new ManagedTransactionImpl(connection);
    }

    public ManagedTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
        try {
            Connection conn = dataSource.getConnection();
            if (conn.getAutoCommit() != autoCommit) {
                conn.setAutoCommit(autoCommit);
            }
            this.connection = conn;
            this.level = level;
            this.closeConnection = true;
            this.delegate = new ManagedTransactionImpl(connection);
        } catch (SQLException e) {
            throw new TransactionException("Error getting a connection.  Cause: " + e, e);
        }
    }

    private class ManagedTransactionImpl extends BaseTransactionState implements TransactionState {
        public ManagedTransactionImpl(Connection connection) {
            // Do nothing
        }

        public void commit() throws SQLException {
            // Do nothing
        }

        public void rollback() throws SQLException {
            // Do nothing
        }

        public void close() throws SQLException {
            if (closeConnection && connection != null) {
                connection.close();
            }
        }

        public Integer getTimeout() throws SQLException {
            return null;
        }
    }

}

七、示例说明

示例一:

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
    // 获取Transaction实例
    Transaction tx = sqlSession.getTransaction();
    // 关闭事务
    tx.close();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    sqlSession.close();
}

示例二:

Transaction transaction = transactionFactory.newTransaction(dataSource, TransactionIsolationLevel.READ_COMMITTED, false);
try {
    // 执行一些数据库操作
    transaction.commit();
} catch (Exception e) {
    transaction.rollback();
} finally {
    transaction.close();
}

八、总结

MyBatis的Transaction事务模块是MyBatis框架的核心模块之一,它为MyBatis应用程序提供了事务管理功能。MyBatis的事务管理模块由Transaction接口、TransactionFactory接口、TransactionIsolationLevel枚举和JdbcTransaction、ManagedTransaction两个类实现,开发者可以根据自己的具体需求进行选择。在实际开发中,我们应该根据项目的实际情况选择合适的事务管理方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MyBatis源码解析之Transaction事务模块 - Python技术站

(0)
上一篇 2023年6月16日
下一篇 2023年6月16日

相关文章

  • JSP 开发之servlet中调用注入spring管理的dao

    下面是关于 JSP 开发中在 Servlet 中调用注入 Spring 管理的 DAO 的完整攻略: 1. Maven 依赖 首先,在 pom.xml 文件中添加以下依赖: <!– Spring Framework –> <dependency> <groupId>org.springframework</gro…

    Java 2023年6月16日
    00
  • 使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤

    以下是使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤: 配置Tomcat 步骤1:下载Tomcat 首先,我们需要下载Tomcat。可以在Tomcat官网下载。下载完成后,将Tomcat压缩包解压到本地合适的目录。 步骤2:在IDEA中添加Tomcat服务器 1.打开IDEA,进入File -> Settings -> B…

    Java 2023年5月20日
    00
  • Java Runtime用法实战案例

    Java Runtime是Java语言提供的一个类库,位于java.lang包中,它提供了访问JVM进程的API,可以执行系统命令,启动新的进程等功能。 获取Runtime实例 Runtime runtime = Runtime.getRuntime(); 通过调用Runtime.getRuntime()方法可以获取当前Java虚拟机的Runtime实例。 …

    Java 2023年5月23日
    00
  • MyEclipse代码提示设置包括html和jsp的代码

    MyEclipse是一款常用的Java开发工具,具有强大的代码提示和自动补全功能,对于提高编程效率十分有帮助。而要完整地设置代码提示,包括HTML和JSP的代码,也并不是一件困难的事情。下面我将为大家介绍详细的设置步骤,包括两个实际的示例。 设置HTML代码提示 在MyEclipse中,设置HTML代码提示需要按照以下步骤进行: 打开MyEclipse软件,…

    Java 2023年6月15日
    00
  • Java实现经典游戏超级玛丽的示例代码

    Java实现经典游戏超级玛丽的完整攻略 Java是一门跨平台的编程语言,能够运行在不同操作系统与硬件平台上。本文将介绍使用Java实现经典游戏超级玛丽的详细攻略,希望能够帮助读者更好地学习Java编程。 1. 搭建游戏框架 首先,我们需要搭建游戏的框架。在Java中,可以使用Swing或JavaFX等GUI库来创建图形化界面。我们选择使用Swing来实现。 …

    Java 2023年5月30日
    00
  • MyBatis几种不同类型传参的方式总结

    Sure! MyBatis几种不同类型传参的方式总结 在MyBatis中,传参是非常重要的一部分。正确的传递参数对于正确的执行SQL语句非常关键。本文将介绍MyBatis的不同传参方式及其使用示例。 1. 基本参数类型 基本参数类型指的是Java中的简单数据类型,如int、String、float等,也包括其相应的包装类型。在Mapper文件中,可以直接使用…

    Java 2023年5月20日
    00
  • 大公司为什么禁止SpringBoot项目使用Tomcat?

    前言 在SpringBoot框架中,我们使用最多的是Tomcat,这是SpringBoot默认的容器技术,而且是内嵌式的Tomcat。同时,SpringBoot也支持Undertow容器,我们可以很方便的用Undertow替换Tomcat,而Undertow的性能和内存使用方面都优于Tomcat,那我们如何使用Undertow技术呢?本文将为大家细细讲解。 …

    Java 2023年4月18日
    00
  • SpringMVC如何在生产环境禁用Swagger的方法

    如果您的Spring MVC项目使用了Swagger来生成文档并进行接口测试,在生产环境下禁用Swagger是一个不错的选择。本文将详细讲解如何在生产环境中禁用Swagger。 方法一:使用Profile 首先,创建一个新的profile,在该profile中配置Swagger禁用。在application.yml文件中添加以下配置,该配置将Swagger在…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部