[英]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
數據庫,但是您應該在文檔中搜索identity
或auto-increment
類型。 您也可以使用guid
類型,但要花費更多。
請記住,程序重新啟動時,您將必須在最后分配的ID之后開始。 但是您仍然不需要隊列,只需一個具有同步nextId
方法的IdProvider
類,該方法將遞增並返回已初始化為最后一個分配的ID的私有變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.