mybatis源码解析(五)-mybatis如何实现的事务控制

  • Post author:
  • Post category:其他



mybatis源码解析(一)-开篇



mybatis源码解析(二)-加载过程



mybatis源码解析(三)-SqlSession.selectOne类似方法调用过程



mybatis源码解析(四)-Mapper方法调用过程



mybatis源码解析(五)-mybatis如何实现的事务控制



mybatis源码解析(六)-配合spring-tx实现事务的原理



mybatis源码解析(七)-当mybatis一级缓存遇上spring

转载请标明出处:


http://blog.csdn.net/bingospunky/article/details/79283104


本文出自

马彬彬的博客

这篇博客主要展示mybatis是如何控制事务的。

下面两个例子分别展示一下我们使用/不使用Trancation的例子。


Code 1

不使用事务,自动提交

    SqlSession session = sqlSessionFactory.openSession(true);
    session.insert("insert into table1(id, name) values(1, 'a');");
    session.insert("insert into table1(id, name) values(2, 'b');");


Code 2

使用事务,不自动提交

    SqlSession session = sqlSessionFactory.openSession(false);
    try {
        session.insert("insert into table1(id, name) values(1, 'a');");
        session.insert("insert into table1(id, name) values(2, 'b');");
        session.commit();
    } catch (Exception e) {
        session.rollback();
    }

在mybatis api中,控制Trancation是在创建

org.apache.ibatis.session.SqlSession

的时候设置boolean类型的参数来实现的。调用方法没有差别,支持事务的最后会调用commoit或者rollback。

创建SqlSession

创建

org.apache.ibatis.session.SqlSession

的过程如下:


Code 3



org.apache.ibatis.session.defaults.DefaultSqlSessionFactory

    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;
        DefaultSqlSession var8;
        try {
            Environment environment = this.configuration.getEnvironment();
            TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            Executor executor = this.configuration.newExecutor(tx, execType);
            var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
        } catch (Exception var12) {
            this.closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
        } finally {
            ErrorContext.instance().reset();
        }
        return var8;
    }

第7行创建了Transaction对象。第8行创建了Executor对象。第9行创建了SqlSession对象。下面第这三个对象做一个简单介绍:

  • 1、

    org.apache.ibatis.session.SqlSession

用户直接操作的对象,该对象对用户调用的方法进行一些简单的处理,然后调用Executor的方法执行具体的操作。

可以注意一下,该对象维护了一个

private boolean dirty;

用来标记在上次commit之后有没有执行新的增、删、改操作。该类的commit会根据这个属性来确定会不会执行jdbc代码的commit方法,也可以强制commit而跳过这个属性的限制。

  • 2、

    org.apache.ibatis.executor.Executor

该对象是具体执行sql的类,它操作的是

org.apache.ibatis.mapping.MappedStatement

,这个对象在执行真正的sql时,会使用jdbc的

java.sql.Connection

,但是它不会去生成、维护这个

java.sql.Connection

,它包含了一个

org.apache.ibatis.transaction.Transaction

,由

Transaction

这个对象去维护

Transaction

  • 3、

    org.apache.ibatis.transaction.Transaction

这是个接口,接口的定义如下:


Code 4



org.apache.ibatis.transaction.Transaction

    public interface Transaction {
        Connection getConnection() throws SQLException;
        void commit() throws SQLException;
        void rollback() throws SQLException;
        void close() throws SQLException;
    }

它的一个实现类

org.apache.ibatis.transaction.jdbc.JdbcTransaction

,这个类里维护了

DataSource

,在需要的时候会创建

java.sql.Connection

,在创建完

java.sql.Connection

后,会根据创建

org.apache.ibatis.session.SqlSession

时传递的参数值,设置

java.sql.Connection

是否自动提交。该类也提供了对

Connection

执行commit、rollback的方法,在

org.apache.ibatis.session.SqlSession

执行commit、rollback方法时,都会传递到这里的方法。

总结

我们使用Jdbc进行事务控制的话,也是调用

java.sql.Connection.setAutoCommit

设置是否开启事务,调用

java.sql.Connection.commit



java.sql.Connection.rollback

进行调或回滚。在mybatis代码中,通过

org.apache.ibatis.session.SqlSession

的创建设置是否支持事务,调用

org.apache.ibatis.session.SqlSession.commit



org.apache.ibatis.session.SqlSession.rollback

方法会映射到对应Jdbc的方法,这样就足以支持了事务。



版权声明:本文为u011647962原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。