Derby - 使用相同的Connection创建PreparedStatement时,获取RETURN_GENERATED_KEYS似乎不是线程安全的

时间:2013-02-16 07:17:29

标签: java jdbc derby javadb

我使用Statement.RETURN_GENERATED_KEYS一个接一个地运行两个INSERT sql调用,每个插入都有自己唯一的ID分配给它。

每个调用都是使用connection.prepareStatement生成的,其中连接可以被不同的线程重用(连接池或嵌入式数据库 - 无论哪种方式都是同一个问题)。

所以当我这样做时:

result = preparedStatement.getGeneratedKeys();
result.next();
return result.getInt(1);

返回的数字似乎不是线程安全的!! 它通常从第一个经过的线程中获取生成的ID。

基本上如果我运行多个线程,INSERTS工作正常,但是然后尝试获取自动生成的唯一ID,它会带回相同的ID。同样,我怀疑这是因为连接是共享的,我是怎么做的

connection.prepareStatement(sqlString, Statement.RETURN_GENERATED_KEYS);

我看到有许多替代参数,但我不熟悉它们。我怎么能以某种方式保证每个preparedStatement稍后会返回它自己唯一的自动生成的ID?

更新: 这似乎只发生在嵌入式德比数据库驱动程序中...

2 个答案:

答案 0 :(得分:2)

要避免这种情况,您必须从以下位置关闭PreparedStatement:

connection.prepareStatement(sqlString, Statement.RETURN_GENERATED_KEYS);

BEFORE 您创建另一个preparedStatement。看起来嵌入式Derby驱动程序中可能存在一个假设,即调用数据库的代码(至少对于INSERTS来说)永远不会被线程化。如果您要对其进行处理,请执行 NOT 使用嵌入式驱动程序。

答案 1 :(得分:1)

您可以在三行代码中使用自己的Java同步块,如:

synchronized( preparedStatement )
{
    result = preparedStatement.getGeneratedKeys();
    result.next();
    return result.getInt(1);
}