接上篇,在开启事务后,执行SQL语句,整理SQL执行流程如下,以插入为例。
SqlMapClientImpl的insert
public Object insert(String id, Object param) throws SQLException { return getLocalSqlMapSession().insert(id, param); }
SqlMapSessionImpl的insert
public Object insert(String id, Object param) throws SQLException { return delegate.insert(sessionScope, id, param); }
SqlMapExecutorDelegate的insert
/** * Call an insert statement by ID * * @param sessionScope - the session * @param id - the statement ID * @param param - the parameter object * @return - the generated key (or null) * @throws SQLException - if the insert fails */ public Object insert(SessionScope sessionScope, String id, Object param) throws SQLException { Object generatedKey = null; MappedStatement ms = getMappedStatement(id); Transaction trans = getTransaction(sessionScope); boolean autoStart = trans == null; try { trans = autoStartTransaction(sessionScope, autoStart, trans); SelectKeyStatement selectKeyStatement = null; if (ms instanceof InsertStatement) { selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement(); } // Here we get the old value for the key property. We'll want it later if for some reason the // insert fails. Object oldKeyValue = null; String keyProperty = null; boolean resetKeyValueOnFailure = false; if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) { keyProperty = selectKeyStatement.getKeyProperty(); oldKeyValue = PROBE.getObject(param, keyProperty); generatedKey = executeSelectKey(sessionScope, trans, ms, param); resetKeyValueOnFailure = true; } StatementScope statementScope = beginStatementScope(sessionScope, ms); try { ms.executeUpdate(statementScope, trans, param); }catch (SQLException e){ // uh-oh, the insert failed, so if we set the reset flag earlier, we'll put the old value // back... if(resetKeyValueOnFailure) PROBE.setObject(param, keyProperty, oldKeyValue); // ...and still throw the exception. throw e; } finally { endStatementScope(statementScope); } if (selectKeyStatement != null && selectKeyStatement.isRunAfterSQL()) { generatedKey = executeSelectKey(sessionScope, trans, ms, param); } autoCommitTransaction(sessionScope, autoStart); } finally { autoEndTransaction(sessionScope, autoStart); } return generatedKey; }
添加操作会获取当前SessionScope的事务信息,如果没有事务,则添加一个默认事务,完成插入操作的自动提交
MappedStatement的executeUpdate方法
public int executeUpdate(StatementScope statementScope, Transaction trans, Object parameterObject) throws SQLException { ErrorContext errorContext = statementScope.getErrorContext(); errorContext.setActivity("preparing the mapped statement for execution"); errorContext.setObjectId(this.getId()); errorContext.setResource(this.getResource()); statementScope.getSession().setCommitRequired(true); try { parameterObject = validateParameter(parameterObject); Sql sql = getSql(); errorContext.setMoreInfo("Check the parameter map."); ParameterMap parameterMap = sql.getParameterMap(statementScope, parameterObject); errorContext.setMoreInfo("Check the result map."); ResultMap resultMap = sql.getResultMap(statementScope, parameterObject); statementScope.setResultMap(resultMap); statementScope.setParameterMap(parameterMap); int rows = 0; errorContext.setMoreInfo("Check the parameter map."); Object[] parameters = parameterMap.getParameterObjectValues(statementScope, parameterObject); errorContext.setMoreInfo("Check the SQL statement."); String sqlString = sql.getSql(statementScope, parameterObject); errorContext.setActivity("executing mapped statement"); errorContext.setMoreInfo("Check the statement or the result map."); rows = sqlExecuteUpdate(statementScope, trans.getConnection(), sqlString, parameters); errorContext.setMoreInfo("Check the output parameters."); if (parameterObject != null) { postProcessParameterObject(statementScope, parameterObject, parameters); } errorContext.reset(); sql.cleanup(statementScope); notifyListeners(); return rows; } catch (SQLException e) { errorContext.setCause(e); throw new NestedSQLException(errorContext.toString(), e.getSQLState(), e.getErrorCode(), e); } catch (Exception e) { errorContext.setCause(e); throw new NestedSQLException(errorContext.toString(), e); } }
iBatis的增、删、改三种操作的SQL的最终都是调用MappedStatement的executeUpdate是执行,这三种操作都需要提交事务。所以操作执行时会设置SessionScope的事务提交标识为真。流程与insert类似,只是少了selectKey标签的处理。
时间: 2024-10-01 13:42:13