zoukankan      html  css  js  c++  java
  • mybatis源码分析(2)——事务概述

    这篇文章主要对mybatis中的事务做一简单的分析,帮助读者理清一些概念。

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

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

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

    Connection.TRANSACTION_NONE

    Connection.TRANSACTION_READ_COMMITTED

    Connection.TRANSACTION_READ_UNCOMMITTED

    Connection.TRANSACTION_REPEATABLE_READ

    Connection.TRANSACTION_SERIALIZABLE

     

    在mybatis中,有一个事务管理器的配置,其中type属性可以配置事务的类型,提供了JDBCMANAGED的配置属性,这就说明在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中,通过一个Enumorg.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 事务处理工具,其官网需翻墙才能访问。

     

  • 相关阅读:
    http-server -S 开启 https 服务
    material-ui react的ui框架 有时间可以看看 chia用的前台ui
    关于vue.js:iview-Bug-5114在iview的Poptip气泡提示内调用DatePicker出现遮挡或同时关闭窗口等冲突问题[转]
    coding 的pages 静态要六分钱一个月,我也是醉了。
    jeesite 有时间看看
    选择单词后 按 ctrl + space 单词发音
    什么是CI/CD
    PostCSS深入学习: PostCSS和Sass、Stylus或LESS一起使用
    浅析requestAnimationFrame
    webpack性能优化
  • 原文地址:https://www.cnblogs.com/hzhuxin/p/3352758.html
Copyright © 2011-2022 走看看