当前位置: 首页 > 知识库问答 >
问题:

当实体带有@Version注释字段或属性时,乐观锁如何自动启用?

邵崇凛
2023-03-14

最近我一直在研究数据库事务,一篇文章引用如下

JPA通过@Version注释自动支持行版本控制。当您具有带有@Version注释字段或属性的实体时,乐观锁定将自动启用。

我的理解是,数据库隔离级别策略是使用不同的锁来维护的,比如

  1. 未提交读取:使用独占写锁定实现
  2. 读取提交:使用共享读锁定和独占写锁定实现。

所以,事务隔离是通过不同的锁定来实现的,我猜是通过使用悲观锁定来实现。

我的问题是,当一个字段被声明为@ Version annotatted时,它会覆盖底层的默认隔离级别并发生乐观锁定吗?

共有2个答案

许华清
2023-03-14

不,您不能使用JPA的乐观锁定覆盖底层数据库的隔离级别。

如果你能以某种方式做到这一点,这样做是没有好处的。

大多数数据库采用READ_COMMITED隔离级别作为默认值。

考虑READ _ COMMITED隔离级别下的以下场景。

  • 两个管理器加载一个产品实体
  • 他们俩都决定涨价,然后保存下来。
  • 一个价格更新在另一个之前提交。
  • 所以一个经理的价格将被另一个经理的价格覆盖,而经理们不知道这一点。

虽然这种情况是微不足道的,但这些事情可能会发生在非平凡的场景中。

通过使用数据库默认隔离级别的乐观锁,可以避免这种意外情况。

希望这有帮助。

洪和风
2023-03-14

不,它们是不同的东西。默认情况下,隔离级别配置为读取提交的,因此在事务提交之前无法读取任何更改。

如果您决定通过@Version使用乐观锁定,则根本不会更改隔离级别,而是假定要使用读取提交的隔离级别,因为我认为在使用乐观锁定时使用读取未提交读取序列化是没有意义的,但您可以。

创建事务时定义隔离级别,通常指定只读模式、隔离级别、传播模式和事务的名称。

乐观锁定由ORM基础结构控制,在持久化时注意对象的正确编号版本。所以,它们是不同的东西。

希望有帮助!

 类似资料:
  • 乐观锁Version 要使用乐观锁,需要使用version标记 type User struct { Id int64 Name string Version int `xorm:"version"` } 在Insert时,version标记的字段将会被设置为1,在Update时,Update的内容必须包含version原来的值。 var user User engine

  • 我读到我们可以使用<code>@version</code>在hibernate中使用version字段实现乐观锁定。然后,通过阅读悲观锁定,我知道了<code>org.hidbernate。LockMode</code>类,它有一些选项,如<code>LockMod。我们可以在中指定的OPTIMISTICetc。 所以我的问题是我是否需要同时使用和?

  • 我试图为现有MongoDB数据库中的文档实现乐观锁定。目前没有字段,我希望避免添加它,因为我们将不得不停止应用程序。 但是有一个date字段,我似乎可以这样使用它: 这就像是对现有文档的一种魅力。但是当我尝试添加一个新文档时,我得到: 找不到能够从[java.lang.Integer]类型转换为[java.util.date]类型的转换器 如果我添加一个整数到日期转换器,那么新文档将保存在数据库中

  • 1. 前言 在锁一节中,我们从粒度和管理两个角度来阐述了锁。如果你还不熟悉锁,请先阅读该小节,再来进行本小节的学习。 本小节我们将继续深挖锁,以开发者和实战的角度来谈锁。 2. 为什么需要锁 2.1 什么是数据竞争 在本节的开头,我们来谈一谈为什么开发程序需要使用锁?如果你有一点并发编程的基础,又或者对多线程有一点熟悉,那么你肯定知道答案,那就是数据竞争。 2.2 数据竞争实例 我们举一个生活的例

  • 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,会产生冲突,解决方案有两种:乐观锁、悲观锁。 悲观锁在这里不讲,自行Google。 乐观锁假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,不完整则更新失败。 乐观锁实现方式 使用整数表示数据版本号.更新时检查版本号是否一致,如果相等,则更新成功,且版本号+1.如果不等,则数据已经被修改过,更新失败。 使用时间戳来实现。 本质上也

  • 问题内容: 使用版本属性对实体进行乐观锁定可以很好地实现,并且易于实现: 实体具有以下类型的属性: 到目前为止,一切都很好。现在,服务方法返回上述实体的数据传输对象(DTO),视图以HTML形式显示。对于更新页面,VERSION属性存储在HTML隐藏字段中,并与表单一起提交。 目的是使用version属性来确保如果显示的信息带有旧版本,则用户的更新将失败。 控制器通过调用包含更新信息(包括版本属性