我需要插入有两列的数据库 -
ID Primary Key String
Data String
这意味着ID每次都应该是唯一的,否则在插入时会抛出duplicate row in unique index
异常。我需要在此范围1-100000
这意味着每个线程应始终使用唯一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);
}
}
}
答案 0 :(得分:2)
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。
答案 1 :(得分:1)
identity
列是数据库为每个插入分配新唯一值的列。见here
我不知道这个XpressMP
数据库,但您应该在文档中搜索identity
或auto-increment
类型。您也可以稍微花费guid
类型使用IdProvider
类型。
请记住,当程序重新启动时,您必须在最后分配的ID之后开始。但是你仍然不需要一个队列,只需要一个带有同步nextId
方法的{{1}}类,该方法递增并返回一个已经初始化为最后一个分配id的私有变量。