zoukankan      html  css  js  c++  java
  • MyBatis openSession(),close(),和commit() 底层代码剖析

    一:MyBatis工具类 中openSession到底做了什么?

            Mybatis工具类

     1     private static final String RESOURCE = "mybatis-config.xml";
     2     private static SqlSessionFactory sqlSessionFactory = null;
     3     private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
     4 
     5 
     6 
     7 
     8     //关闭sqlsession
     9     public static void closeSession(){
    10         SqlSession session = (SqlSession) threadLocal.get(); // 2
    11         threadLocal.set(null);
    12         if (session !=null){
    13             session.close();
    14         }
    15     }
    16 
    17     public static SqlSession getSessionTwo() {
    18         //读取配置文件
    19         try {
    20             InputStream stream = Resources.getResourceAsStream(RESOURCE);
    21             sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
    22 
    23             return sqlSessionFactory.openSession();   //返回openSession
    24         } catch (IOException e) {
    25             e.printStackTrace();
    26         }
    27 
    28         return null;
    29     }

     首先点开openSession 发现踏实sqlsessionFactory的一个方法

     1 package org.apache.ibatis.session;
     2 
     3 import java.sql.Connection;
     4 
     5 public interface SqlSessionFactory {
     6     SqlSession openSession();
     7 
     8     SqlSession openSession(boolean var1);
     9 
    10     SqlSession openSession(Connection var1);

    然后再看这 个方法的实现类DefaultSqlSessionFactory

    这里主要返回他自己类的一个方法openSessionFroDataSource()  (数据源) 并赋值 autoCommit 为false

    然后 进入这个方法  

     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;
        }
    
    
    可以看到他这个方法主要是初始化一些configure.xml的配置信息和DefaultSqlSession

    所以openSession的主要就是初始化了
    configure.xml的配置信息和DefaultSqlSession

     二:MyBatis工具类 中sqlSession.close()底层为什么回滚事务?

     首先进入 close()找到他的实现类DefaultsqlSession

       DefaultsqlSession里的close方法

     

      

         

    session.close(); 底层为什么可以回滚事务?????
    DefaultsqlSession里的close方法
     public void close() {
            try {
                this.executor.close(this.isCommitOrRollbackRequired(false));
                this.dirty = false;
            } finally {
                ErrorContext.instance().reset();
            }
    
        }
        
     进入Executor接口  查看他的实现类BaseExecutor 找到close()方法
    public void close(boolean forceRollback) {   //需要传入一个boolean参数
            try {
                try {
                    this.rollback(forceRollback);   //为true则rollback
                } finally {
                    if(this.transaction != null) {   
                        this.transaction.close();
                    }
    
                }
            } catch (SQLException var11) {
                log.warn("Unexpected exception on closing transaction.  Cause: " + var11);
            } finally {
                this.transaction = null;
                this.deferredLoads = null;
                this.localCache = null;
                this.localOutputParameterCache = null;
                this.closed = true;
            }
    
        }
    然后再看下executor.close()里的参数
    this.executor.close(this.isCommitOrRollbackRequired(false));
        ------>isCommitOrRollbackRequired
        private boolean isCommitOrRollbackRequired(boolean force) {
            return true || false;
        }
    //可以看到如果没有提交之前调用close() ,isComitOrRollbackRequired()返回的是true
    然后Executor的实现类BaseExecutor的close()方法为参数
    forceRollback为true 然后进入rollback(forceRollBack)参数为true
    看下最终的rollback方法  
    public void rollback(boolean required) throws SQLException {
    if(!this.closed) {
    try {
    this.clearLocalCache();
    this.flushStatements(true);
    } finally {
    if(required) {
    this.transaction.rollback(); //如果传入的参数为 true 则进行事务 回滚
    }

    }
    }
     
    
    

    另外至于为什么没有提交之前close会回滚事务,提交了之后则是关闭事务

    主要在于Executor的实现类BaseExecutor的

    isCommitOrRollbackRequired()参数改变了。

    三:commit()

        session.commit(); 为什么能提交事务,他的实现和close()的实先基本差不多,主要是

    isCommitOrRollbackRequired()方法

         参数的真假,真则提交,假便关闭
        session会话




    000000000写的好low啊自嘲




       

  • 相关阅读:
    30-Transformation(HDU4578)-区间线段树(复杂)
    87-区间线段树(板子)--那个苑区的人最瘦
    86-区间线段树-模板
    1-2018-3-2小球碰撞
    85-取石子-威佐夫博弈
    83-取石子-尼姆博弈
    82-珠子染色-置换群
    2018.3.29 设计模式之单例模式详解
    2018.3.27 Mac 配置Tomcat
    2018.3.26 Linux下学习命令
  • 原文地址:https://www.cnblogs.com/zhangyu0217----/p/7120690.html
Copyright © 2011-2022 走看看