使用preparedStatement选择时更新数据库

时间:2009-03-06 06:30:20

标签: java prepared-statement

我正在使用PreparedStatement从MS SQL数据库中选择数据子集。 在遍历结果集时,我还想更新行。目前我使用的是这样的东西:

prepStatement = con.prepareStatement(
                    selectQuery,
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_UPDATABLE);


 rs = prepStatement.executeQuery();

while(rs.next){
rs.updateInt("number", 20)
rs.updateRow();
}

使用正确的值更新数据库,但我收到以下异常:

Optimistic concurrency check failed. The row was modified outside of this cursor.

我用谷歌搜索过,但未能就此问题找到任何帮助。

如何防止此异常?或者既然程序确实做了我想做的事情,我可以忽略它吗?

2 个答案:

答案 0 :(得分:2)

记录在从数据库中检索的那一刻(通过光标)和您尝试将其保存的时刻之间进行了修改。如果可以独立于记录的其余部分安全地更新number列,而与已将number列设置为其他某个值的其他进程无关,则可能是很想做:

con.execute("update table set number = 20 where id=" & rs("id") )

然而,竞争条件仍然存在,您的更改可能会被另一个进程覆盖。

最好的策略是忽略异常(记录未更新),可能将失败的记录推送到队列(在内存中),然后再做第二遍对失败的记录进行重新评估(重新评估query中的条件并进行适当更新 - 如果情况不是这样,则将number <> 20添加为query中的一个条件。)重复直到没有更多记录失败。最终所有记录都将更新。

答案 1 :(得分:0)

假设您确切知道要更新的行,我会这样做

  • 将您的AUTOCOMMIT设置为OFF
  • SET ISOLATION Level to SERIALIZABLE
  • SELECT row1,row1 FROM table WHERE somecondition FOR UPDATE
  • 更新行
  • COMMIT

这是通过悲观锁定实现的(假设数据库支持行锁定,它应该可以工作)