mybatis源码分析(2)——事务概述
这篇文章主要对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)——事务概述的更多相关文章
- MyBatis 源码分析-项目总览
MyBatis 源码分析-项目总览 1.概述 本文主要大致介绍一下MyBatis的项目结构.引用参考资料<MyBatis技术内幕> 此外,https://mybatis.org/mybat ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- MyBatis源码分析(5)——内置DataSource实现
@(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...
- MyBatis源码分析(4)—— Cache构建以及应用
@(MyBatis)[Cache] MyBatis源码分析--Cache构建以及应用 SqlSession使用缓存流程 如果开启了二级缓存,而Executor会使用CachingExecutor来装饰 ...
- MyBatis源码分析(3)—— Cache接口以及实现
@(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...
- Mybatis源码分析-BaseExecutor
根据前文Mybatis源码分析-SqlSessionTemplate的简单分析,对于SqlSession的CURD操作都需要经过Executor接口的update/query方法,本文将分析下Base ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- MyBatis 源码分析 - 内置数据源
1.简介 本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑.搞懂这些数据源的实现,可使大家对数据源有更深入的认识.同时在配置这些数据源时,也会更清楚每种属性的意义和用途.因此,如果大家想知其 ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
随机推荐
- SQL server 2012 如何取上个月的最后一天
好吧 QQ群里被问到这种问题,还是这里写一下吧. DECLARE @date DATETIME = getdate(); SELECT EOMONTH (@date) AS 'Last Day Of ...
- 使用RPC 调用NameNode中的方法
用户在Client 端是很难对 NameNode中的信息进行直接访问的, 所以 ,在Hadoop系统中为 Client端 提供了一系列的方法调用,这些方法调用是通过RPC 方法来实现的, 根据RPC ...
- ios 可变参数(va_list,va_start,va_end)
例如:UIAlertView的init方法中的otherButtonTitles:(NSString *)otherButtonTitles, ...等多个可变参数. ios实现传递不定长的多个参数的 ...
- OS X EL Capitan安装Cocoapods 报错ERROR
升级OS X EL Capitan10.11之后,原来的pod不能用了,重新安装cocoapods,发现 在运行 “sudo gem install cocoapods” 的时候出现问题: ERROR ...
- Mac OS X 在Finder新建文本文件
Automator 新建一个 Application添加一个动作 "Run AppleScript"代码如下 on run {input, parameters} tell app ...
- .net 安卓IOS跨平台des加解密双向的(可以互相加解密)
#region 跨平台加解密(c# 安卓 IOS) // public static string sKey = "12345678"; // /// // /// 解密 // / ...
- struts 模型驱动
情景: 有一个用来处理用户的UserAction 类, 该动作类实现了 ModelDriven 接口. 当用户触发UserAction 动作时, ModelDriven 拦截器将调用相关UserAct ...
- STL之优先队列
STL 中优先队列的使用方法(priority_queu) 基本操作: empty() 如果队列为空返回真 pop() 删除对顶元素 push() 加入一个元素 size() 返回优先队列中拥有的元素 ...
- MinGW 仿 linux 开发环境
MinGW 默认安装 MSYS.通常打开的 MinGW Shell 其实 MSYS,MinGW 作为一个组件存在. MSYS -- Minimal SYStem,是一个 Bourne Shell 解释 ...
- IOS 学习笔记 2015-03-24 OC-API-常用结构体
一 标题 常用结构体 二 API 1 NSRange 表示一个范围 A 实例化 NSRange rg={3,5};//第一参数是起始位置第二个参数是长度 B 实例化 NSRange rg2=NSMak ...