2013-06-20 108 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