簡體   English   中英

插入時應為每個線程分配唯一的ID

[英]Each thread should be assigned unique id while inserting

我需要插入具有兩列的數據庫中-

ID Primary Key String
Data String

因此,這意味着ID每次都應該是唯一的,否則在插入時ID會duplicate row in unique index異常中引發duplicate row in unique index 我需要在1-100000范圍內選擇ID

因此,這意味着每個線程應始終使用唯一的ID-

下面是我編寫的多線程程序,每次從ArrayBlockingQueue獲取后,它將以不同的唯一ID插入數據庫。

那么該程序是否是線程安全的? 還是還有其他更好的方法來為每個線程每次獲取唯一ID? 還是下面的程序會導致duplicate row in unique index

private static LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();

public static void main(String[] args) {

        for (int i = 1; i <= 100000; i++) {
            availableExistingIds.add(i);
        }

        BlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(200000, false, availableExistingIds);

        ExecutorService service = Executors.newFixedThreadPool(10);

            for (int i = 0; i < noOfTasks * noOfThreads; i++) {
                service.submit(new ThreadTask(pool));
            }
}   

class ThreadTask implements Runnable {

    private BlockingQueue<Integer> pool;
    private int id;

    public ThreadTask(BlockingQueue<Integer> pool) {
        this.pool = pool;
    }

    @Override
    public void run() {

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

            id = pool.take();

            preparedStatement.setString(1, String.valueOf(id));
            preparedStatement.setString(2, ACCOUNT);

            preparedStatement.executeUpdate();

       } finally {
         pool.offer(id);
        }

    }
}   

pool.offer(id)意味着您將使用過的id重新放回隊列中-這樣以后就可以被另一個線程重用。 這可能是個問題(由於隊列是FIFO,因此在第100,001次插入時將獲得重復的ID)。

無論如何,當靜態AtomicInteger不必使用隊列就可以執行相同的操作時,這似乎非常復雜:

class ThreadTask implements Runnable {

    private final AtomicInteger id;

    ThreadTask(AtomicInteger id) {
        this.id = id; //in your main thread: id = new AtomicInteger(minId);
    }

    @Override
    public void run() {
        dbConnection = getDBConnection();
        preparedStatement = dbConnection.prepareStatement(INSERT_SQL);

        preparedStatement.setString(1, String.valueOf(id.getAndIncrement()));
        preparedStatement.setString(2, ACCOUNT);

        preparedStatement.executeUpdate();
    }
}

注意:如上所述,您的數據庫可能可以為您分配唯一的ID。

identity列是數據庫在每次插入時為其分配一個新的唯一值的列。 這里

我不知道這個XpressMP數據庫,但是您應該在文檔中搜索identityauto-increment類型。 您也可以使用guid類型,但要花費更多。

請記住,程序重新啟動時,您將必須在最后分配的ID之后開始。 但是您仍然不需要隊列,只需一個具有同步nextId方法的IdProvider類,該方法將遞增並返回已初始化為最后一個分配的ID的私有變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM