0

XpressMPデータベースに挿入しようとしています。これは新しいデータベースです。複数のスレッドでデータベースに挿入するためのマルチスレッドプログラムを作成しました。

私は2つの列を持つ以下のテーブルに挿入しようとしています-ID and ACCOUNT

ID      String Primary Key
ACCOUNT String

そのため、現在、主キーとしてIDを持っています。また、データベースに挿入するたびに新しいIDを生成する必要があります。そうしないと、例外が表示されます-

duplicate row in unique index:

そのために、私はこのように不変のクラスを作成しました。このクラスでは、新しいスレッドが要求するたびに生成されるuser_idがあります-

public final class ConstantsFiles {

    private static Random rnd = new Random();
    private final static int NO_OF_DIGITS = 10;

    public static String user_id;

    public final static String ACCOUNT = "{\"lv\":null,\"lmd\":13597}";

    public final static String INSERT_SQL = "INSERT INTO COPY"
        + "("
        + "ID, ACCOUNT) VALUES"
        + "(?, ?)";

    /**
     * Generates a Random user id
     * 
     */

    public static String getUser_id() {
        StringBuilder sb = new StringBuilder(NO_OF_DIGITS);
        for (int i = 0; i < NO_OF_DIGITS; i++)
            sb.append((char) ('0' + rnd.nextInt(10)));

        return sb.toString();
    }

}

以下は、上記の不変クラスにあるgetメソッドから毎回新しいIDを取得するマルチスレッドコードです-

@Override
public void run() {

    try {
        dbConnection = getDBConnection();
        preparedStatement = dbConnection.prepareStatement(ConstantsFiles.INSERT_SQL);

        preparedStatement.setString(1, ConstantsFiles.getUser_id());
        preparedStatement.setString(2, ConstantsFiles.ACCOUNT);

        preparedStatement.executeUpdate();

    } catch (Exception e) {
        LOG.error(e);
    } finally {
        // close connection
    }
    }

各スレッドは毎回新しいユーザーIDを生成し、毎回同じACCOUNT値を使用して、データベースに挿入します。

しかし、どういうわけか、ある段階でそれは私に例外を投げかけています-

duplicate row in unique index:COPY_PRIMARY_KEY_

つまり、ある時点で同じUSER IDを使用してデータベースに挿入しているため、例外がスローされます。

それが起こっている理由についての考え。クラスを不変にし、getメソッドを追加しました。では、何が問題なのでしょうか。私のクラスは不変ではないのでしょうか?

新しいスレッドごとに生成される新しいユーザーIDを使用してデータベースに挿入する必要がありますが、毎回同じACCOUNT値を使用できます。

4

1 に答える 1

1

ランダムは一意を保証するものではありません。データベースとのトランザクションを開き、挿入する前に未使用であることを確認する必要があります。そうしないと、最終的に発生することが保証されます。

編集:私はXpressMPをまったく知りませんが、疑似SQLでは次のようなことをする必要があります。

BEGIN
    DECLARE @free = NULL
    LOCK COPY
    SELECT INTO @free ID FROM COPY WHERE ID = ?
    IF free IS NULL
        INSERT ....
    UNLOCK COPY
END
于 2013-02-05T19:50:37.173 に答える