MyBatis事务管理

MyBatis的事务管理是由TransactionFactoryTransaction两个接口定义的,TransactionFactory负责生成Transaction,这是一个典型的工厂模式。

官方提供了事务管理的两种模式:

  • Managed:对应ManagedTransactionFactoryManagedTransaction
  • JDBC:对应JdbcTransactionFactoryJdbcTransaction

重点看一下Transaction中提交和回滚的实现:

java 复制代码
public class ManagedTransaction implements Transaction {
  @Override
  public void commit() throws SQLException {
    // Does nothing
  }

  @Override
  public void rollback() throws SQLException {
    // Does nothing
  }
 }
java 复制代码
public class JdbcTransaction implements Transaction {
  @Override
  public void commit() throws SQLException {
    if (connection != null && !connection.getAutoCommit()) {
      if (log.isDebugEnabled()) {
        log.debug("Committing JDBC Connection [" + connection + "]");
      }
      connection.commit();
    }
  }

  @Override
  public void rollback() throws SQLException {
    if (connection != null && !connection.getAutoCommit()) {
      if (log.isDebugEnabled()) {
        log.debug("Rolling back JDBC Connection [" + connection + "]");
      }
      connection.rollback();
    }
  }
}

可以看出,这两者的主要区别在于ManagedTransaction不会进行实际的事务提交和回滚,而是交由外部进行控制,而JdbcTransaction是我们能进行实际事务提交和回滚的,所以如果我们要手动控制事务,应该指定事务管理器为JdbcTransactionFactory,例如在mybatis的配置文件中:

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED"></dataSource>
    </environment>
  </environments>
</configuration>

Transaction和实际执行查询的SqlSession又是什么关系呢?原来是创建SqlSession的时候会交由Executor管理,一起传给SqlSession

java 复制代码
public class DefaultSqlSessionFactory implements SqlSessionFactory {
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
}

当我们执行SqlSessioncommit()时,实际上是调用Executorcommit(),进而调用Transactioncommit()

java 复制代码
public class DefaultSqlSession implements SqlSession {
  @Override
  public void commit(boolean force) {
    try {
      executor.commit(isCommitOrRollbackRequired(force));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
}
java 复制代码
public abstract class BaseExecutor implements Executor {
  @Override
  public void commit(boolean required) throws SQLException {
    if (closed) {
      throw new ExecutorException("Cannot commit, transaction is already closed");
    }
    clearLocalCache();
    flushStatements();
    if (required) {
      transaction.commit();
    }
  }
}
相关推荐
程序猿乐锅1 分钟前
【苍穹外卖|Day01】项目初识:从多模块结构到 OpenAPI 接口文档踩坑
java·spring·maven·mybatis
我不是懒洋洋2 分钟前
【C++】内存管理与模板(C++内存管理方式、new和delete的实现原理、malloc/free和new/delete的区别、函数模板、类模板)
c语言·开发语言·c++·青少年编程·visual studio
雪的季节3 分钟前
Qt多窗口架构设计需求简介
开发语言·qt
李白的天不白4 分钟前
针对你遇到的 Client.Timeout exceeded 问题,我判断是防火墙拦截了 HTTPS 流量
java
linweidong8 分钟前
Java 后端开发面试 50 个高频易混淆知识点详解
java·spring boot·spring·spring cloud·面试·mybatis·spring事务
码语智行8 分钟前
应用启动和关闭监听器功能分析
java·spring boot
Resky08188 分钟前
什么是 Spring IOC:倒过来让容器帮你 new,而不是你到处 new
java·spring
AutumnWind04208 分钟前
【JDK动态代理源码梳理】
java·后端·spring
韦胖漫谈IT9 分钟前
面向对象 vs 函数式背后的思维差异
开发语言
Xin_ye1008612 分钟前
C# 零基础到精通教程 - WPF 深度专题:3D 图形与视觉增强
开发语言·c#·wpf