2

Statement.RETURN_GENERATED_KEYS を使用して、2 つの 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 を返すことをどうにかして保証するにはどうすればよいですか?

更新: これは、組み込みの derby データベース ドライバーでのみ発生するようです...

4

2 に答える 2

2

これを回避するには、PreparedStatement を次の場所から閉じる必要があります。

connection.prepareStatement(sqlString, Statement.RETURN_GENERATED_KEYS);

別のPreparedStatementを作成する前に。Embedded Derby ドライバーでは、データベースを呼び出すコード (少なくとも INSERTS の場合) は決してスレッド化されないという前提があるようです。スレッド化する場合は、組み込みドライバーを使用しないでください。

于 2013-02-16T08:05:46.250 に答える
1

次のように、3行のコードの周りに独自のJava同期ブロックを使用できます。

synchronized( preparedStatement )
{
    result = preparedStatement.getGeneratedKeys();
    result.next();
    return result.getInt(1);
}
于 2013-02-16T15:43:49.957 に答える