阅读iBatis源码时,对事务相关的代码,没太关注,导致今天项目技术演练时对同事的疑问,解释不清楚。自己都不清楚的东西,怎么可能向别人解释清楚呢?所以,就干脆继续看iBatis源码,完整跟踪事务的处理流程。重新分析代码,发现iBatis原来使用了代理模式,同时理解了iBatis的线程安全的保证机制及事务控制流程。
顶层类图
线程安全的保证
public Object insert(String id, Object param) throws SQLException {
return getLocalSqlMapSession().insert(id, param);
}
protected SqlMapSessionImpl getLocalSqlMapSession() {
SqlMapSessionImpl sqlMapSession = (SqlMapSessionImpl) localSqlMapSession.get();
if (sqlMapSession == null || sqlMapSession.isClosed()) {
sqlMapSession = new SqlMapSessionImpl(this);
localSqlMapSession.set(sqlMapSession);
}
return sqlMapSession;
}
事务基础
iBatis的SqlMapClient提供了事务处理方法如下:
事务相关的类图
事务的状态转换图如下:
SqlMapSessionImpl实现TransactionManager事务相关的四个方法,本质上就是操作它关联的SessionScope中有关事务的属性,即Transaction 和TransactionState。例如:startTransaction方法会根据配置的事务管理器,新建一个事务对象,并设置事务状态为STATE_STARTED。其他跟事务有关的处理大多都是根据操作调用JDBC的Connection的对应的事务处理方法。endTransaction方法会根据事务状态,提交或者回滚SQL操作,最后会关闭JDBC语句和数据库连接。
iBatis源码中使用到的Session的含义是与数据库的一次完整的会话过程,从开启到结束,体现在四个事务操作方法中,所有的SQL执行操作,最终都是通过JDBC的Connection完成的。