Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.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 以原子方式更新多行_Java_Database_Jdbc_Atomic - Fatal编程技术网

Java 以原子方式更新多行

Java 以原子方式更新多行,java,database,jdbc,atomic,Java,Database,Jdbc,Atomic,我需要执行select,然后以原子方式更新ResultSet中的一些行 我正在使用的代码看起来很简单: stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = stmt.executeQuery("SELECT ..."); while (rs.next()) { if (conditions_to_update) { rs.updateS

我需要执行select,然后以原子方式更新ResultSet中的一些行

我正在使用的代码看起来很简单:

stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery("SELECT ...");

while (rs.next()) {
    if (conditions_to_update) {
        rs.updateString(...);
        rs.updateRow();
    }
}
我能保证更新将以原子方式执行吗?如果没有,我如何保证? 如果任何其他进程更改了通过updateRow更新的数据库行,会发生什么情况?有没有办法锁定结果集中的行?
使用事务。

这里可能有一大堆技术和概念,当您开始考虑多线程/多请求应用程序时,事情开始变得相当棘手

正如Iassevk所述,您应该研究使用以确保更新的原子性-一个非常低级的示例是按照以下思路进行操作:

...
con.setAutoCommit(false);
try {
  while (rs.next()) {
    if (conditions_to_update) {
      rs.updateString(...);
      rs.updateRow();
    }
  }
  con.setAutoCommit(true);
} catch (Exception ex) {
  //log the exception and rollback
  con.rollback();
} finally {
  con.close();
}
然后,所有更新都将批处理到同一事务中。如果任何更新生成了异常,例如无效值或连接部分失败,则整个批次将回滚。最后加上,因为我是它的冠军;p

然而,这并不能解决第二个问题,即两个相互竞争的方法试图更新同一个表-竞争条件。在我看来,这里有两种主要的方法——每种方法都有优点和缺点

最简单的方法是——这需要最少的代码更改,但有一个很大的缺点。假设与大多数应用程序一样,更多的是读而不是写:锁定表将阻止所有其他用户查看数据,代码很可能会挂起,等待锁释放,然后连接超时开始并引发异常

更复杂的方法是确保执行这些更新的方法以线程安全的方式实现。为此目的:

此表的所有更新都通过一个类进行 该类实现了单例模式,或者将更新方法公开为静态方法 更新方法使用关键字来防止竞争条件 如果任何其他进程更改了通过updateRow更新的数据库行,会发生什么情况?有没有办法锁定结果集中的行

在Oracle中,您可以通过发出以下SQL来标记某些行以进行更新

select cola, colB from tabA for update;

尝试更新此行的下一个事务/线程/应用程序将获得异常。有关更多详细信息,请参见此-

谢谢。我正在寻找一种方法,使用JDBC或至少标准SQL来锁定表、具体行甚至单个单元格。我想那是不可能的。