如何在批量更新中使用乐观锁定?我正在使用SimpleJdbcTemplate
,对于单行,我可以构建更新sql,以增加版本列的值,并在WHERE子句中包含版本。
[不幸的是,使用Oracle驱动程序时,结果int[] updated = simpleJdbcTemplate.batchUpdate
不包含行数。所有元素均为-2,表示未知行数。
与单独执行所有更新相比,还有其他更高效的方法吗?这些批次平均包含5个项目(仅),但最多可以包含250个。
这里只是大声思考-如果驱动程序中的批处理支持存在问题,您可以尝试使用单个查询来实现相同目的,从而使批处理的相关性降低。 (您知道,批处理是为了避免多个查询的延迟,但是即使批处理单个查询,延迟仍然存在。)
这是通过单个查询即可实现乐观更新的方式
由于可以将临时表用作选择查询,因此可以找到要更新的行,然后将其作为更新查询提交。 (当然,所有事务都在交易中。)
以说明:
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)
[当我为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一起使用,即使将批处理更新与乐观锁定混合使用,它也可以像超级按钮一样工作。