当前位置: 首页 > article >正文

MyBatis 事务源码分析

先来看看在JAVA事务的相关技术,在JAVA中有两类事务,JDBC事务和JTA事务,如果是JDBC类型的事务,则是由Connection类来控制的。如果创建一个Connection对象时,没有显示调用

setTransactionIsolation(int level) 方法,则Connection使用当前数据库默认的事务隔离级别,数据库的默认事务隔离级别可以通过相应的SQL语句进行查询,例如在Mysql数据库下可使用 select @@tx_isolation;语句查看当前数据库的事务隔离级别。

JDBC的Connection类针对事务的隔离性定义了五个隔离级别。

Connection.TRANSACTION_NONE

Connection.TRANSACTION_READ_COMMITTED

Connection.TRANSACTION_READ_UNCOMMITTED

Connection.TRANSACTION_REPEATABLE_READ

Connection.TRANSACTION_SERIALIZABLE

在mybatis中,有一个事务管理器的配置,其中type属性可以配置事务的类型,提供了JDBC或MANAGED的配置属性,这就说明在mybatis中事务的管理方式有两个事务管理器的实现,都是针对JDBC事务的事务管理器(非JTA事务),分别是:

  org.apache.ibatis.transaction.jdbc.JdbcTransaction

  org.apache.ibatis.transaction.managed.ManagedTransaction

这两个类都实现了org.apache.ibatis.transaction.Transaction接口,Transaction接口定义了如下方法:

   Connection getConnection() throws SQLException;
   void commit() throws SQLException;
   void rollback() throws SQLException;
   void close() throws SQLException;

通过这些方法可以看出这个接口实际是对Connection类进行了包装,包括了Connection的创建、提交、回滚、关闭动作。并且,其中ManagedTransaction类的commit方法和rollback方法中没有做任何事,也就是说这个类是不控制事务的提交和回滚的,而交由外部容器去管理事务的提交与回滚,外部容器(可以是Spring 容器或EJB容器)通过声明式事务的方式进行管事。

在mybatis中,通过一个Enum类org.apache.ibatis.session.TransactionIsolationLevel

来定义了事务的隔离级别:

public enum TransactionIsolationLevel {
  NONE(Connection.TRANSACTION_NONE),
  READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
  READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
  REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
  SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);

  private final int level;

  private TransactionIsolationLevel(int level) {
    this.level = level;
  }

  public int getLevel() {
    return level;
  }
}

TransactionIsolationLevel类中定义的事务隔离级别其实就是引用了Connection类中的事务隔离级别,下面分别对这几种隔离级别进行说明: 

TRANSACTION_NONE:表示不支持事务的常量

TRANSACTION_READ_UNCOMMITTED:表示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量

TRANSACTION_READ_COMMITTED:不可重复读和虚读可以发生

TRANSACTION_REPEATABLE_READ:虚读可以发生

TRANSACTION_SERIALIZABLE:指示不可以发生脏读、不可重复读和虚读的常量。

再来理解下什么是脏读、不能重复读、虚读(又叫幻读)

脏读:如果一个事务对数据进行了更新,但事务还没有提交,另一个事务就可以“看到”该事务没有提交的更新结果。这样造成的问题是,如果第一个事务回滚,那么第二个事务在此之前所“看到”的数据就是一笔脏数据。

不可重复读:指同个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的。所以TRANSACTION_READ_COMMITTED是无法避免不可重复读和虚读。

幻读:指同样一个查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。

最后再总结下:mybatis只是对JDBC事务提供了事务管理器的封装,如果想在mybatis中使用JTA事务,需要我们自行实现org.apache.ibatis.transaction.Transaction接口,对此Spring框架提供了解决方案,可能通过mybatis+spring+atomikos的整合来完成。或者采用EJB容器也可以提供JTA事务的支持。


http://www.kler.cn/a/135715.html

相关文章:

  • 弹性盒子布局(Flexbox)详细介绍
  • Qwen2 系列大型语言模型
  • sqoop import将Oracle数据加载至hive,数据量变少,只能导入一个mapper的数据量
  • 用户裂变数据分析
  • ROM修改进阶教程------安卓14 安卓15去除app签名验证的几种操作步骤 详细图文解析
  • 面试:TCP、UDP如何解决丢包问题
  • 2024年软件测试面试必看系列,看完去面试你会感谢我的!!
  • [Jenkins] Docker 安装Jenkins及迁移流程
  • nginx代理本地服务请求,避免跨域;前端图片压缩并上传
  • ajax,axios,fetch
  • Nodejs--Express框架使用
  • 编程刷题网站以及实用型网站推荐
  • Oracle Data Redaction和Oracle Data Pump
  • C#asp.net考试系统+sqlserver
  • 设计模式-创建型模式-单例模式
  • Flink之OperatorState
  • Android MQTT开发之 Hivemq MQTT Client
  • 全志R128内存泄漏调试案例
  • 鸿蒙4.0开发笔记之DevEco Studio之配置代码片段快速生成(三)
  • 【Python 千题 —— 基础篇】输出可以被5整除的数
  • 嵌入式QTGit面试题
  • 计算机毕业设计选题推荐-高校后勤报修微信小程序/安卓APP-项目实战
  • 可逆矩阵的性质
  • 获取阿里云Docker镜像加速器
  • Arduino驱动DS18B20数字温度传感器(温湿度传感器)
  • OpenCV快速入门:直方图、掩膜、模板匹配和霍夫检测