在我的代码库中,我们有一个如下所示的MyBatis查询,
INSERT INTO TABLE_A(
ID,
NAME,
VERSION
)
VALUES (
#id#,
#name#,
(select NVL(max(version), 0 ) + 1 from SAE_PROC_SETTING where name = #name#)
)unique约束针对列名和版本。如果多个用户同时插入值,有时我们会得到唯一的约束错误。当我们检查时,名称和版本是相同的,并如预期的那样抛出错误。
我的问题是,MyBatis如何处理内部查询
(select NVL(max(version), 0 ) + 1 from TABLE_Awhere name = #name#)这个查询是由Oracle提交给oracle,然后MyBatis先执行SELECT,然后执行INSERT查询,还是MyBatis先执行SELECT,然后替换INSERT中的值,然后在Oracle中提交INSERT查询(由MyBatis执行2步)?
如果像第二个选项一样处理,当两个人同时使用相同的名称插入时,两个人都有可能获得相同的版本。然后,当尝试插入时,我们将得到UniqueConstraint错误。
请让我知道MyBatis是如何在内部处理这个问题的。任何指针都可以。
谢谢,SD
发布于 2016-07-26 23:50:27
MyBatis只是替换查询参数,然后通过prepareStatement传递查询。
日志将insert显示为一条语句。
2016-07-26 17:34:23.776 DEBUG 91036 --- [ main] sample.mybatis.mapper.CityMapper.insert : ==> Preparing: insert into city (name, state, country) values ((select DISTINCT 'a' from city), 'CA', 'US');
2016-07-26 17:34:23.777 DEBUG 91036 --- [ main] sample.mybatis.mapper.CityMapper.insert : ==> Parameters:
2016-07-26 17:34:23.779 DEBUG 91036 --- [ main] sample.mybatis.mapper.CityMapper.insert : <== Updates: 1然后我调试它,当它被调用这个方法(source github)时,只需传递INSERT case:
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
.....
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
....
}
break;
case FLUSH:
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
....
}https://stackoverflow.com/questions/34730156
复制相似问题