Java 使用ibatis检索新插入行的ID时的并发性问题
我正在使用iBatis/Java和Postgres 8.3。 当我在ibatis中插入时,我需要返回id。 我使用下表来描述我的问题: 创建表sometable id serial NOT NULL,sometfield VARCHAR10; 通过运行create语句自动生成序列sometable_id_seq 目前,我使用以下sql映射:Java 使用ibatis检索新插入行的ID时的并发性问题,java,postgresql,ibatis,Java,Postgresql,Ibatis,我正在使用iBatis/Java和Postgres 8.3。 当我在ibatis中插入时,我需要返回id。 我使用下表来描述我的问题: 创建表sometable id serial NOT NULL,sometfield VARCHAR10; 通过运行create语句自动生成序列sometable_id_seq 目前,我使用以下sql映射: <insert id="insertValue" parameterClass="string" > INSERT INTO sometabl
<insert id="insertValue" parameterClass="string" >
INSERT INTO sometable ( somefield ) VALUES ( #value# );
<selectKey keyProperty="id" resultClass="int">
SELECT last_value AS id FROM sometable_id_seq
</selectKey>
</insert>
这似乎是ibatis检索新插入的id的方法。ibatis首先运行INSERT语句,然后询问最后一个id的序列。
我怀疑这是否适用于许多并发插入
这会引起问题吗?比如返回错误插入的id
另请参见我关于的相关问题。这肯定是错误的。使用:
select currval('sometable_id_seq')
或者更好:
INSERT INTO sometable ( somefield ) VALUES ( #value# ) returning id
它将返回您插入的id。以下是一个简单的示例:
<statement id="addObject"
parameterClass="test.Object"
resultClass="int">
INSERT INTO objects(expression, meta, title,
usersid)
VALUES (#expression#, #meta#, #title#, #usersId#)
RETURNING id
</statement>
我有另一个想法。ibatis调用insert方法委托类:com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate,代码为:
您可以看到insert和select运算符位于事务中。因此,我认为insert方法不存在一致性问题。因此您认为它会导致问题。我的另一个问题是关于如何将插件插入。。返回。。声明进入ibatis因为我不能在这里发布链接,我在问题的末尾添加了它当然会。使用psql中的2个连接进行尝试。至于ibatis——我不知道它是什么,但它看起来与java相关——这意味着我无能为力。
Integer id = (Integer) executor.queryForObject("addObject", object);
object.setId(id);
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);
}