Mybatis是一个支持自定义SQL语句,存储过程,高级映射的数据持久化框架。
它封装了JDBC,在框架中隐藏了几乎所有的JDBC的API,这里说下从源码的角度Mybatis 3.x (笔者用的是3.2.8)是如何封装JDBC来实现事务处理的。
回忆下mybatis是怎么使用事务管理的,session.commit(),session.rollback(), JDBC呢,是connection.commit(),connection.rollback()。所以这篇文章的内容就变成了如何从session.commit()到connection.commit()。
首先从session来看看,我们获得一个session对象其实是DefaultSqlSession对象,这个类中的commit() 方法如下。
public void commit() { commit(false); } public void commit(boolean force) { try { executor.commit(isCommitOrRollbackRequired(force)); dirty = false; } catch (Exception e) { throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } private boolean isCommitOrRollbackRequired(boolean force) { return (!autoCommit && dirty) || force; }
然后到CachingExecutor 中的方法
public void commit(boolean required) throws SQLException { delegate.commit(required); tcm.commit(); } //也许对这执行commit的对象不熟悉,看下面 private Executor delegate; private TransactionalCacheManager tcm = new TransactionalCacheManager();
所以真正我们关心的事务是另外一个Executor,BaseExecutor中commit()方法
public void commit(boolean required) throws SQLException { if (closed) throw new ExecutorException("Cannot commit, transaction is already closed"); clearLocalCache(); flushStatements(); if (required) { transaction.commit(); } }
前面两个方法是跟缓存相关,只有最后一个才是我们关心的,JDBCTransaction类中的commit()
public void commit() throws SQLException { if (connection != null && !connection.getAutoCommit()) { if (log.isDebugEnabled()) { log.debug("Committing JDBC Connection [" + connection + "]"); } connection.commit(); } }
现在我们明白了,JDBCTransaction中包装了一个connection的对象。这也是我们在使用mybatis配置文件时设置的事务管理类。
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <!--这里--> <property name="..." value="..."/> </transactionManager> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>