如何使用批量更新的乐观锁定?我正在使用SimpleJdbcTemplate
,对于单行,我可以构建更新sql,它增加版本列值并包含WHERE子句中的版本。
不幸的是,使用oracle驱动程序时,结果int[] updated = simpleJdbcTemplate.batchUpdate
不包含行计数。所有元素都是-2表示未知的行数。
除了单独执行所有更新之外,还有其他更高效的方法吗?这些批次平均包含5个项目(仅限),但可能最多250个。
答案 0 :(得分: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)
答案 1 :(得分: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一起使用,即使将批处理更新与乐观锁定混合使用,它也可以像魅力一样发挥作用。