2

だから私は Apache Derby で Java を使用しており、レコードを挿入しようとしていますが、同じキーを持つレコードがまだ存在しない場合にのみ、データベースではなくコードに存在させたいすべての値があるためです。 derbys のダミー テーブルを使用します (db2 の DUAL に類似) これは私が使用しているクエリです (md5 が主キーです)

PreparedStatement stmt = conn.prepareStatement("INSERT INTO artwork (md5,image) " +
               "SELECT ?,?" +
               "FROM SYSIBM.SYSDUMMY1 " +
               "WHERE NOT EXISTS ( SELECT 1 FROM artwork WHERE md5=?)");

    stmt.setString(1, key);
    stmt.setBinaryStream(2, new ByteArrayInputStream(imageData), imageData.length);
    stmt.setString(3, key);

動作しているように見えましたが、2 つのスレッドが同じアートワークを挿入しようとするようにコードをマルチスレッド化すると、インデックスに重複する値を入力することに関するエラーが発生します。

同時に 1 つのスレッドのみがメソッドを呼び出せるようにメソッドを同期すると、そのようなエラーは発生しませんが、そもそも WHERE NOT EXISTS 値を追加する目的が無効になります。

それで、私のクエリは私が思っていることをしていませんか、それともここで一般的な概念を誤解していますか?

4

1 に答える 1

0

情報:このソリューションは機能しません。詳細については、コメントを参照してください。私はそれをここに残したので、解決策を探す人はこれも試す必要はありません。

私自身はまだ問題を抱えていませんが、サブクエリを最適化すれば回避できると思います。このように(私はそれをテストしていません、多分それは改善が必要です):

PreparedStatement stmt = conn.prepareStatement("INSERT INTO artwork (md5,image) " +
           "SELECT ?,?" +
           "FROM SYSIBM.SYSDUMMY1 left join artwork exi on ? = md5" +
           "WHERE exi.md5 IS NULL");

stmt.setString(1, key);
stmt.setBinaryStream(2, new ByteArrayInputStream(imageData), imageData.length);
stmt.setString(3, key);
于 2012-01-09T16:16:43.730 に答える