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

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.commitjava.sql.Connection.rollback进行调或回滚。在mybatis代码中,通过org.apache.ibatis.session.SqlSession的创建设置是否支持事务,调用org.apache.ibatis.session.SqlSession.commitorg.apache.ibatis.session.SqlSession.rollback方法会映射到对应Jdbc的方法,这样就足以支持了事务。

你可能感兴趣的:(♚java♚,mybatis源码解析)