这篇文章主要对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事务的支持。关于具体整合方案,可关注我的后续文章。

注:Atomikos 是一款 Java/JTA 事务处理工具,其官网需翻墙才能访问。

mybatis源码分析(2)——事务概述的更多相关文章

  1. MyBatis 源码分析-项目总览

    MyBatis 源码分析-项目总览 1.概述 本文主要大致介绍一下MyBatis的项目结构.引用参考资料<MyBatis技术内幕> 此外,https://mybatis.org/mybat ...

  2. MyBatis源码分析-SQL语句执行的完整流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  3. MyBatis源码分析(5)——内置DataSource实现

    @(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...

  4. MyBatis源码分析(4)—— Cache构建以及应用

    @(MyBatis)[Cache] MyBatis源码分析--Cache构建以及应用 SqlSession使用缓存流程 如果开启了二级缓存,而Executor会使用CachingExecutor来装饰 ...

  5. MyBatis源码分析(3)—— Cache接口以及实现

    @(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...

  6. Mybatis源码分析-BaseExecutor

    根据前文Mybatis源码分析-SqlSessionTemplate的简单分析,对于SqlSession的CURD操作都需要经过Executor接口的update/query方法,本文将分析下Base ...

  7. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  8. MyBatis 源码分析 - 内置数据源

    1.简介 本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑.搞懂这些数据源的实现,可使大家对数据源有更深入的认识.同时在配置这些数据源时,也会更清楚每种属性的意义和用途.因此,如果大家想知其 ...

  9. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

随机推荐

  1. SQL server 2012 如何取上个月的最后一天

    好吧 QQ群里被问到这种问题,还是这里写一下吧. DECLARE @date DATETIME = getdate(); SELECT EOMONTH (@date) AS 'Last Day Of ...

  2. 使用RPC 调用NameNode中的方法

    用户在Client 端是很难对 NameNode中的信息进行直接访问的, 所以 ,在Hadoop系统中为 Client端 提供了一系列的方法调用,这些方法调用是通过RPC 方法来实现的, 根据RPC ...

  3. ios 可变参数(va_list,va_start,va_end)

    例如:UIAlertView的init方法中的otherButtonTitles:(NSString *)otherButtonTitles, ...等多个可变参数. ios实现传递不定长的多个参数的 ...

  4. OS X EL Capitan安装Cocoapods 报错ERROR

    升级OS X EL Capitan10.11之后,原来的pod不能用了,重新安装cocoapods,发现 在运行 “sudo gem install cocoapods” 的时候出现问题: ERROR ...

  5. Mac OS X 在Finder新建文本文件

    Automator 新建一个 Application添加一个动作 "Run AppleScript"代码如下 on run {input, parameters} tell app ...

  6. .net 安卓IOS跨平台des加解密双向的(可以互相加解密)

    #region 跨平台加解密(c# 安卓 IOS) // public static string sKey = "12345678"; // /// // /// 解密 // / ...

  7. struts 模型驱动

    情景: 有一个用来处理用户的UserAction 类, 该动作类实现了 ModelDriven 接口. 当用户触发UserAction 动作时, ModelDriven 拦截器将调用相关UserAct ...

  8. STL之优先队列

    STL 中优先队列的使用方法(priority_queu) 基本操作: empty() 如果队列为空返回真 pop() 删除对顶元素 push() 加入一个元素 size() 返回优先队列中拥有的元素 ...

  9. MinGW 仿 linux 开发环境

    MinGW 默认安装 MSYS.通常打开的 MinGW Shell 其实 MSYS,MinGW 作为一个组件存在. MSYS -- Minimal SYStem,是一个 Bourne Shell 解释 ...

  10. IOS 学习笔记 2015-03-24 OC-API-常用结构体

    一 标题 常用结构体 二 API 1 NSRange 表示一个范围 A 实例化 NSRange rg={3,5};//第一参数是起始位置第二个参数是长度 B 实例化 NSRange rg2=NSMak ...