MyBatis openSession(),close(),和commit() 底层代码剖析

时间:2021-04-08 15:50:59

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

Mybatis工具类

     private static final String RESOURCE = "mybatis-config.xml";
private static SqlSessionFactory sqlSessionFactory = null;
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); //关闭sqlsession
public static void closeSession(){
SqlSession session = (SqlSession) threadLocal.get(); //
threadLocal.set(null);
if (session !=null){
session.close();
}
} public static SqlSession getSessionTwo() {
//读取配置文件
try {
InputStream stream = Resources.getResourceAsStream(RESOURCE);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream); return sqlSessionFactory.openSession(); //返回openSession
} catch (IOException e) {
e.printStackTrace();
} return null;
}

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

 package org.apache.ibatis.session;

 import java.sql.Connection;

 public interface SqlSessionFactory {
SqlSession openSession(); SqlSession openSession(boolean var1); SqlSession openSession(Connection var1);

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

MyBatis  openSession(),close(),和commit()  底层代码剖析

这里主要返回他自己类的一个方法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啊自嘲