首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >乐观锁定工作,但没有OptimisticLockException或任何其他

乐观锁定工作,但没有OptimisticLockException或任何其他
EN

Stack Overflow用户
提问于 2020-09-08 16:31:02
回答 1查看 901关注 0票数 0

在测试JPA乐观锁定时,我有简单的实体和相应的服务/控制器。锁定属性如下所示:

代码语言:javascript
复制
@Version
@Column(name = "opt_lock", nullable = false)
private short optLock;

测试场景。我有一份已经存在的记录。实体包含ID、optLock和2个数据字段valueA和valueB。这两种方法都被设置为1. .save方法调用上有断点,它被包装在试图捕获所有RuntimeExceptions中。通过TransactionTemplate启动的整个事务也是如此。

在控制器上,我调用PUT方法将值( valueA和valueB )分别更新为2-5.实体按ID读取,只更新值valueA和valueB,没有触摸锁定字段。挂起.save方法调用断点,该方法被配置为只阻塞单个线程。

同样的操作,但是值为200-1。线程也被阻塞。

我取消了第二次更新,验证数据被正确更新到200-1,在已发布的语句中正确发送了200-1值,update语句中使用的optLock值也是数据库中存在于先前记录中的值。对,是这样。

我取消了与第一次更新相关的线程,我看到有人试图用正确的值2-5更新记录,使用了正确的optLock,即。在此操作之前存在于db中的对象。此时,db中不存在组合ID-optLock。因此,无法更新此记录。但事实并非如此。没错!

但是..。也不例外。为什么?

在尝试调试它时,我尝试从项目中删除net.ttddy.数据源--如果它不吞服它(它不会);如果整个场景开始失败--如果我删除了@Version注释(确实如此),我尝试通过hibernate代码进行调试,但是我没有发现任何问题。

有什么建议可以导致缺失异常吗?

更新:用普通的EntityManager替换spring的内容,这是一样的。试图在Intellij IDEA之外运行它,事实证明,它有时可以对您的db调用执行非常令人惊讶的操作,而且也是一样的。更令人惊讶的是(对我来说)如果我引入刷新和清除调用并在它们上放置断点,线程在刷新和清除之后在线挂起,以某种方式锁定持久化上下文或其他东西,但是第二个线程只是挂起直到第一个线程完成,所以这不能用来模拟锁异常,因此我认为如果对持久性上下文的访问是同步的(可能在默认设置中,这将是我当前的设置),这也不会在现实生活中造成问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-10 13:06:12

问题原因:在我们的例子中,问题是由批处理更新引起的,配置为:

代码语言:javascript
复制
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true

并使用buggy甲骨文驱动程序:

代码语言:javascript
复制
<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc6</artifactId>
  <version>11.2.0.3</version>
</dependency>

我们一直在使用它,因为我们的一些产品仍然是在weblogic上,并且为weblogic获得正确的依赖关系并不需要那么容易,所以我们选择不触及起作用的东西。

由于此驱动程序中的错误,jpa乐观锁和批处理更新的组合确实有效,但不会引发异常。如果我们对...batch_size...batch_versioned_data进行评论,这似乎是可行的。大学甚至认为只需评论一下...batch_versioned_data就行了。

链接:

它似乎不是甲骨文特有的错误,其他dbs也有:Hibernate optimistic locking different behavior between Postgres and MariaDb

Optimistic locking batch update

Hibernate saves stale data with hibernate.jdbc.batch_versioned_data

解决方案:

正如@Vlad在上面提到的一个链接中所指出的,将oracle驱动程序升级到下面似乎会有所帮助。

代码语言:javascript
复制
<dependency>
  <groupId>com.oracle.ojdbc</groupId>
  <artifactId>ojdbc8</artifactId>
  <version>19.3.0.0</version>
</dependency>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63798043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档