0

我正在尝试插入 XpressMP 数据库,这是一个新数据库。我编写了一个多线程程序,以将其插入到具有多个线程的数据库中。

我正在尝试用两列插入下表 -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
    }
    }

其中每个线程每次都会生成一个新的 USER 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 回答