2013-02-06 101 views
0

被分配唯一的ID,我需要插入其中有兩個columns-每個線程應該同時插入

ID Primary Key String 
Data String 

數據庫因此,這意味着ID應該是唯一的每一次,否則會拋出一個異常duplicate row in unique index插入時。我需要在這個範圍內1-100000

之間做出選擇ID因此,這意味着每個線程應該使用唯一的ID始終在線

下面是多線程程序我寫了,將後每次插入到數據庫不同的獨特的ID從ArrayBlockingQueue獲得。

所以這個程序將是線程安全或不是?或者還有沒有其他更好的方法來獲得每個線程每次唯一的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

哪個數據庫?你不能使用「身份」類型嗎? –

+0

我正在使用一個名爲XpressMP的新數據庫。你能否以身份解釋我是什麼意思? – AKIWEB

回答

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爲您服務。

+0

感謝assylias的建議。所以在你上面提到的例子中。每次從1開始,它都會增加id的權利?如果我需要從特定範圍獲得唯一身份證,那麼呢? – AKIWEB

+0

@ Nevzz03您可以將初始化更改爲'id = new AtomicInteger(lowerBoundOfYourRange);'或者有一個構造函數接受AtomicInteger並管理主代碼中的id範圍。 – assylias

+0

我已經更新了一個示例,其中id傳遞給了構造函數 - 確保所有任務都使用相同的方法。 – assylias

1

identity列是數據庫爲每個插入指定一個新的唯一值的列。見here

我不知道這XpressMP數據庫,但你應該尋找文檔的identityauto-increment類型。您也可以使用​​類型,成本稍高。

請記住,當程序重新啓動時,您必須在上次分配的ID之後開始。但你仍然不需要隊列,只需要一個帶有同步nextId方法的IdProvider類,該方法遞增並返回已初始化爲最後分配的ID的私有變量。

相關問題