有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当使用相同的连接创建PreparedStatement时,java Derby获取RETURN_生成的_键似乎不是线程安全的

我使用with语句一个接一个地运行两个INSERT sql调用。返回生成的密钥每个插入都有自己的唯一ID

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

因此,当我这样做时:

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

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

基本上,如果我运行多个线程,插入可以正常工作,但如果尝试获取自动生成的唯一ID,它会返回相同的ID。我再次怀疑这是因为连接是共享的,我是如何做到的

connection.prepareStatement(sqlString, Statement.RETURN_GENERATED_KEYS);

我看到有许多替代参数,但我不熟悉它们。我怎样才能保证每个preparedStatement稍后都会返回它自己唯一的自动生成ID

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


共 (2) 个答案

  1. # 1 楼答案

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

    connection.prepareStatement(sqlString, Statement.RETURN_GENERATED_KEYS);
    

    在创建另一个preparedStatement之前。看起来在嵌入式Derby驱动程序中可能存在这样一种假设,即调用数据库的代码(至少对于插入)永远不会被线程化。如果要执行线程,请不要使用嵌入式驱动程序

  2. # 2 楼答案

    您可以围绕三行代码使用自己的Java同步块,如下所示:

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