2013-06-20 109 views
0

我想弄清楚使用PreparedStatement executeBatch()方法的最佳方式。使用PreparedStatement的最佳方法executeBatch()

一種方法我試過是:

try{ 
    prepStmt1 = conn.prepareStatement("update table set done='yes' where phone=?"); 
    while (operatorsQuery.next()) { 
      logger.info("phone: "+ phone + ", operator: " + operator); 

      process(); //0.5-1 second long 
      prepStmt1.setString(1, "0"+phone); 
      prepStmt1.addBatch(); 
    } 
prepStmt1.executeBatch(); 
} 
catch{...} 
finally{ 
    closeStatmentand(prepStmt1); 
} 

我對這段代碼遇到的問題是,該方案可以在中間退出,那麼它可能達不到則ExecuteBatch()方法。

第二種方式我想:

try{ 
    prepStmt1 = conn.prepareStatement("update table set done='yes' where phone=?"); 
    while (operatorsQuery.next()) { 
      logger.info("phone: "+ phone + ", operator: " + operator); 

      process(); //0.5-1 second long 
      prepStmt1.setString(1, "0"+phone); 
      prepStmt1.addBatch(); 
      if ((j + 1) % 100 == 0) { 
       prepStmt1.executeBatch(); 
      } 
    } 
prepStmt1.executeBatch(); 
} 
catch{...} 
finally{ 
    closeStatmentand(prepStmt1); 
} 

這是做到這一點的最優選的方法是什麼?

+0

發帖時的例子確保編譯和運行 –

+0

你是問你是否應該打破批成已知大小 – DaveH

+0

這似乎很奇怪,該程序可以(在第二種情況下100?)在執行過程中關閉。如果程序結束是基於用戶交互的,請告訴用戶他尚未完成,並通知他後果。這樣用戶可以決定他是否想要丟失數據或想要等待。 –

回答

1

通過使用批量更新,查詢不會發送到數據庫,除非您擔心用戶可能會退出該程序並且未達到執行,否則請不要將特定的呼叫發送到executeBatch();,爲什麼不逐一執行更新。並且連接默認設置爲autoCommit(true);

如果應用程序已關閉,則無法調用提交,並且批量更新在調用對execute的明確調用之前,查詢尚未發送到數據庫。

執行增量批處理會做。

======= =======編輯

如果您的問題真的是性能,你有你的應用程序的突然退出問題,請嘗試使用Java消息服務或JMS。 JMS使您能夠異步發送消息,這意味着您的應用程序會將這些「數據」轉發給JMS,而不是等待響應,然後您將對JMS進行編程以將其插入數據庫。 JMS也具有足夠的持久性,當應用程序/服務器關閉時,發送的數據(也稱爲隊列)在其恢復後仍然有效。

雖然JMS不適合初學者,並且很難從頭開始實施。希望這有助於: http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html

+0

我已經嘗試過,但它只需要很長時間,每100次迭代執行一次批量似乎更有效率。 – susparsy

+0

我可以知道爲什麼應用程序會在進程中間退出嗎?當應用程序意外退出時,您希望進行提交是非常不尋常的。 – mel3kings

+0

是的,我知道它的不尋常,該應用程序使得process()如你在代碼中看到的一樣。每個過程應該只做一次!所以我保留在數據庫中完成的每個進程的id(phone_num)。 – susparsy