Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用PreparedSelect语句时更新数据库_Java_Prepared Statement - Fatal编程技术网

Java 使用PreparedSelect语句时更新数据库

Java 使用PreparedSelect语句时更新数据库,java,prepared-statement,Java,Prepared Statement,我正在使用PreparedStatement从MS SQL数据库中选择数据的子集。 在遍历resultset时,我还想更新行。现在我用的是这样的东西: prepStatement = con.prepareStatement( selectQuery, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); rs

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

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.
我已经在谷歌上搜索过了,但在这个问题上找不到任何帮助


如何防止此异常?或者,由于程序确实执行了我希望它执行的操作,我可以忽略它吗?

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

con.execute("update table set number = 20 where id=" & rs("id") )
但是,竞争条件持续存在,您的更改可能会被另一个进程覆盖


最好的策略是忽略异常(记录未更新),可能将失败的记录推送到队列(内存中),然后对失败的记录进行第二次传递(重新评估
query
中的条件,并根据需要进行更新-将
number 20
添加为
query
中的条件之一,如果情况并非如此。)重复操作,直到没有更多记录失败。最终将更新所有记录。

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

  • 将自动提交设置为关闭
  • 将隔离级别设置为可序列化
  • 从更新条件所在的表中选择行1,行1
  • 更新行
  • 承诺

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

您能告诉我们正在使用哪个事务隔离级别吗?…以及您更新的确切查询和确切列是什么吗?可能是“其他人”吗是谁触发了您这边的Optimistic lock异常,并实际执行了您看到的更新?:)不,更新只发生在一个地方,我的进程是唯一访问数据库的进程啊!这只能意味着您的查询返回重复的记录,第一次更新很好,第二次失败。:)为什么会这样?