乐观锁定批处理更新

问题描述 投票:1回答:2

如何在批量更新中使用乐观锁定?我正在使用SimpleJdbcTemplate,对于单行,我可以构建更新sql,以增加版本列的值,并在WHERE子句中包含版本。

[不幸的是,使用Oracle驱动程序时,结果int[] updated = simpleJdbcTemplate.batchUpdate不包含行数。所有元素均为-2,表示未知行数。

与单独执行所有更新相比,还有其他更高效的方法吗?这些批次平均包含5个项目(仅),但最多可以包含250个。

java jdbc optimistic-locking
2个回答
2
投票

这里只是大声思考-如果驱动程序中的批处理支持存在问题,您可以尝试使用单个查询来实现相同目的,从而使批处理的相关性降低。 (您知道,批处理是为了避免多个查询的延迟,但是即使批处理单个查询,延迟仍然存在。)

这是通过单个查询即可实现乐观更新的方式

  • 构建一个临时表,其中包含行更新所需的条件,然后将更新查询重写为该表的联接。 (例如,将实时数据中的当前时间戳与临时表中的时间戳进行外部联接。)如果实时数据中的时间戳尚未更新,则将从您的临时表中选择该行。

由于可以将临时表用作选择查询,因此可以找到要更新的行,然后将其作为更新查询提交。 (当然,所有事务都在交易中。)

以说明:

TempUpdateTable
---------------
id,        // id of the row to be updated
timestamp, // timestamp data originally fetched
data1      // data to be updated
data2
dataN

这将提供所有要更新的数据的ID,您可以将其存储以供以后参考

SELECT d.id FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE t.timestamp=d.timestamp

然后可以在更新语句中使用同一查询

UPDATE YourData
SET data=t.data1
SET data=t.data2  //etc...
FROM TempUpdateTable t WHERE t.id IN
  (SELECT d.in FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE d.timestamp=d.timestamp)

0
投票

[当我为Hibernate工作时,我们注意到较旧的Oracle JDBC驱动程序版本未正确报告更新计数,这就是Hibernate过去使用乐观锁定为实体禁用批量更新的原因。

但是,从Hibernate 5开始,这不再是默认策略,因为JDBC驱动程序可以更好地处理批处理更新计数。

因此,在您的情况下,您需要将Oracle JDBC驱动程序更新为至少12c。请注意,Oracle JDBC驱动程序是向后和向前兼容的,因此即使在数据库服务器端的Oracle 11g上,也可以使用它。

自2019年9月以来,您甚至可以从Maven Central获取Oracle JDBC驱动程序:

<dependency>
    <groupId>com.oracle.ojdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>19.3.0.0</version>
</dependency>

我将驱动程序的版本19与Oracle 18 XE一起使用,即使将批处理更新与乐观锁定混合使用,它也可以像超级按钮一样工作。

© www.soinside.com 2019 - 2024. All rights reserved.