1

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

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.

我已经用谷歌搜索了它,但在这个问题上找不到任何帮助。

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

4

2 回答 2

2

记录在从数据库中检索(通过光标)到您尝试将其保存回来的那一刻之间已被修改。如果number列可以独立于记录的其余部分独立于已经将number列设置为其他值的其他进程安全地更新,您可能会尝试这样做:

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

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

最好的策略是忽略异常(记录未更新),可能将失败的记录推送到队列(在内存中),然后对失败的记录进行第二次传递(重新评估条件query并酌情更新 -如果还不是这种情况,请添加number <> 20为条件之一。)重复直到没有更多记录失败。query最终所有记录都会被更新。

于 2009-03-06T14:17:48.973 回答
0

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

  • 将您的自动提交设置为关闭
  • 将隔离级别设置为可序列化
  • SELECT row1, row1 FROM table WHERE somecondition FOR UPDATE
  • 更新行
  • 犯罪

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

于 2009-07-09T04:24:51.443 回答