文档章节

mybatis源码分析之事务管理器

u
 udbwcso
发布于 2016/04/20 16:08
字数 1008
阅读 539
收藏 4

上一篇:mybatis源码分析之Configuration

主要分析了构建SqlSessionFactory的过程中配置文件的读取.

这次重点分析mybatis的事务管理器

仍旧从官网给的例子着手分析,配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
  <configuration>
      <environments default="development">
        <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
          </dataSource>
        </environment>
      </environments>
      <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
      </mappers>
  </configuration>

 

在根结点configuration下有environments和mappers两个结点.

environments:环境,mybatis可以配置多个环境即可以将 SQL 映射应用于多种数据库之中.如开发,测试,生产对应不同的数据库.

mappers:映射器,提供映射文件的地址.

在environment下的transactionManager就是现在要重点分析的对象.

mybatis中有两种类型的事务管理器,JDBC和MANAGED.

JDBC:直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。

MANAGED:不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。

对例子进行分析,之前分析过

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

 

现在再来分析

SqlSession session = sqlSessionFactory.openSession();

DefaultSqlSessionFactory里的openSession

public SqlSession openSession() {
  return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}

 

openSessionFromDataSource

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();
  }
}

 

看一下各个类之间的关系

JdbcTransaction和ManagedTransaction对应事务管理器的两种类型JDBC和MANAGED.

由于ManagedTransaction几乎没做什么,所以重点分析JdbcTransaction.

因为JdbcTransaction直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。

那么直接来看看JDBC的事务

java.sql.Connection

/**
 * A constant indicating that transactions are not supported.
 */
int TRANSACTION_NONE             = 0;

/**
 * A constant indicating that
 * dirty reads, non-repeatable reads and phantom reads can occur.
 * This level allows a row changed by one transaction to be read
 * by another transaction before any changes in that row have been
 * committed (a "dirty read").  If any of the changes are rolled back,
 * the second transaction will have retrieved an invalid row.
 */
int TRANSACTION_READ_UNCOMMITTED = 1;

/**
 * A constant indicating that
 * dirty reads are prevented; non-repeatable reads and phantom
 * reads can occur.  This level only prohibits a transaction
 * from reading a row with uncommitted changes in it.
 */
int TRANSACTION_READ_COMMITTED   = 2;

/**
 * A constant indicating that
 * dirty reads and non-repeatable reads are prevented; phantom
 * reads can occur.  This level prohibits a transaction from
 * reading a row with uncommitted changes in it, and it also
 * prohibits the situation where one transaction reads a row,
 * a second transaction alters the row, and the first transaction
 * rereads the row, getting different values the second time
 * (a "non-repeatable read").
 */
int TRANSACTION_REPEATABLE_READ  = 4;

/**
 * A constant indicating that
 * dirty reads, non-repeatable reads and phantom reads are prevented.
 * This level includes the prohibitions in
 * <code>TRANSACTION_REPEATABLE_READ</code> and further prohibits the
 * situation where one transaction reads all rows that satisfy
 * a <code>WHERE</code> condition, a second transaction inserts a row that
 * satisfies that <code>WHERE</code> condition, and the first transaction
 * rereads for the same condition, retrieving the additional
 * "phantom" row in the second read.
 */
int TRANSACTION_SERIALIZABLE     = 8;

 

事务隔离级别

TRANSACTION_NONE:不支持事务

TRANSACTION_READ_UNCOMMITTED:允许脏读、不可重复的读和虚读.

TRANSACTION_READ_COMMITTED:不允许脏读,允许不可重复的读和虚读.

TRANSACTION_REPEATABLE_READ:不允许脏读和不可重复的读,允许虚读.

TRANSACTION_SERIALIZABLE:不允许脏读、不可重复的读和虚读.

脏读:一个事务对数据进行更新,但事务还没有提交,另一个事务就可以取到该事务没有提交的更新结果。

不可重复读:同一个事务在整个事务过程中对同一笔数据进行多次读取,每次读取结果都不同。

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

不可重复读:列值的不同; 虚读:记录数量的不同。

 

© 著作权归作者所有

共有 人打赏支持
u
粉丝 80
博文 66
码字总数 15709
作品 0
武汉
私信 提问
mybatis源码分析之SqlSession的创建过程

mybatis之SqlSessionFactory mybatis源码分析之Configuration mybatis源码分析之事务管理器 以上是之前的分析,在mybatis源码分析之事务管理器里分析到了事务管理器 SqlSession session = s...

udbwcso
2016/04/21
1K
0
关于MyBatis sqlSession的一点整理

原文地址:关于MyBatis sqlSession的一点整理 工作中,需要学习一下MyBatis sqlSession的产生过程,翻看了mybatis-spring的源码,阅读了一些mybatis的相关doc,对mybatis sqlSession有了一些...

Realfighter
2015/01/04
0
1
ORM框架 hibernate和mybatis 连接数据详解

工作中,需要学习一下MyBatis sqlSession的产生过程,翻看了mybatis-spring的源码,阅读了一些mybatis的相关doc,对mybatis sqlSession有了一些认知和理解,这里简单的总结和整理一下。 首先...

LYQ1990
2016/04/28
37
0
mybatis源码解读(四)——事务的配置

  上一篇博客我们介绍了mybatis中关于数据源的配置原理,本篇博客介绍mybatis的事务管理。   对于事务,我们是在mybatis-configuration.xml 文件中配置的:      关于解析 标签在上一...

ysocean
05/12
0
0
企业 SpringBoot 教程 (七)springboot开启声明式事务

springboot开启事务很简单,只需要一个注解@Transactional 就可以了。因为在springboot中已经默认对jpa、jdbc、mybatis开启了事事务,引入它们依赖的时候,事物就默认开启。当然,如果你需要...

itcloud
09/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark性能优化之道

Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势 本文结合实例详细阐明了Spark数据倾斜的几种场景以及对应的解决方案,包括避免数据源倾斜,调整并行度,使用自定义Partition...

GordonNemo
10分钟前
2
0
大数据驱动业务决策,CDN实时日志重磅上线

摘要: 阿里云CDN上线了实时日志功能,打通日志服务(SLS)的能力,将CDN采集的实时日志,在小于60秒的时间内投递至日志服务,进行实时、交互式分析和报表呈现。通过CDN日志的实时分析,可以快...

阿里云官方博客
16分钟前
1
0
springCloud学习笔记系列(3)-服务容错保护:Spring Cloud Feign

Feign包含了Ribbon和Hystrix,这个在实战中才慢慢体会到它的意义,所谓的包含并不是Feign的jar包包含有Ribbon和Hystrix的jar包这种物理上的包含,而是Feign的功能包含了其他两者的功能这种逻...

快乐的小火柴
17分钟前
1
0
各种数据库数据类型差异

文本 整数 浮点数 decimal Hive数据库 create table default.foo ( a DECIMAL, -- Defaults to decimal(10,0) b DECIMAL(20), -- Defaults to decimal(20,0) c DECIMAL(9, 7), d DE......

了凡川
22分钟前
3
0
springboot中filter的用法

一、在spring的应用中我们存在两种过滤的用法,一种是拦截器、另外一种当然是过滤器。我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别。 二、f...

xiaomin0322
40分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部