如何使 Hibernate @Lock 注释适用于 Oracle DB?

2024-04-04

我偶然发现 Oracle DB 中锁定行的问题。锁的目的是防止多个事务从数据库读取数据,因为这些数据会影响新数据的生成,并且会在事务中发生更改。

为了进行锁定,我将 @Lock 注释放在 SpringData find 方法上,该方法检索参与事务的数据。

@Lock(LockModeType.PESSIMISTIC_WRITE)
User findUserById(@Param("id") String operatorId);

执行此代码后,我收到日志消息

org.hibernate.loader.Loader - HHH000444: Encountered request for locking however dialect reports that database prefers locking be done in a separate select (follow-on locking); results will be locked after initial query executes

此外,它没有影响和原因

org.springframework.dao.DataIntegrityViolationException: could not execute batch; SQL [insert into ...]

使用实体管理器重写锁即可解决该问题

entityManager.lock(userByIdWithLockOnReadWrite, LockModeType.PESSIMISTIC_WRITE);    

or

entityManager.unwrap(Session.class).lock(userByIdWithLockOnReadWrite, LockMode.PESSIMISTIC_WRITE);

该问题不会出现在 MariaDB (MySQL) 上。

也许使用注释有一些特殊的规则?


你之前这么说:

锁的目的是防止多个事务 从数据库读取数据,因为该数据影响生成 新数据并在交易方面发生变化。

甲骨文使用MVCC (Multiversion Concurrency Control) https://vladmihalcea.com/how-does-mvcc-multi-version-concurrency-control-work/所以读者不会阻止作家,作家也不会阻止读者。即使您使用 Oracle 获取了行级锁,并且在未提交的情况下修改了该行,其他事务仍然可以读取最后提交的值。

与此日志消息相关:

org.hibernate.loader.Loader - HHH000444: Encountered request for locking however dialect reports that database prefers locking be done in a separate select (follow-on locking); results will be locked after initial query executes

后续锁定机制是由于Oracle在进行Oracle 11g分页时无法应用锁,使用DISTINCT or UNION ALL.

如果您使用的是 Oracle 12i,则可以将 Hibernate 方言更新为Oracle12cDialect由于 Oracle 12 使用 SQL 标准分页并且不再需要派生表查询,因此分页和锁定将正常工作。

这在 MariaDB 或任何其他数据库中都不会发生。这只是 Oracle 12 之前的限制。

如果您使用 Hibernate 5.2.1,我们添加了一个新提示HINT_FOLLOW_ON_LOCKING http://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/jpa/QueryHints.html#HINT_FOLLOW_ON_LOCKING这会禁用此机制。

因此,您的 Spring Data 查询将变为:

@QueryHints(value = { @QueryHint(name = "hibernate.query.followOnLocking", value = "false")}, forCounting = false)
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findUserById(@Param("id") String operatorId);

您也可以手动应用它:

User user = entityManager.createQuery(
    "select u from User u where id = :id", User.class)
.setParameter("id", id);
.unwrap( Query.class )
.setLockOptions(
    new LockOptions( LockMode.PESSIMISTIC_WRITE )
        .setFollowOnLocking( false ) )
.getSingleResult();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使 Hibernate @Lock 注释适用于 Oracle DB? 的相关文章

随机推荐

  • 如何在 Ansible playbook api 中设置“--limit”选项

    我正在编写 python 脚本来运行 ansible playbook 使用 Ansible 2 4 2 0 据我所知有一个选择 limit 这可以限制 Ansible 在特定主机上的运行 例如 这是 etc ansible hosts t
  • 使用 cblas 库时出现“对‘cblas_ddot’的未定义引用”

    我正在测试 cblas ddot 我使用的代码来自link https stackoverflow com questions 14470799 calling ddot function in blas library我将其修复为 inc
  • 为什么当我添加产品图像代码时不支持“产品名称”并且“列“产品名称”不允许为 NULL;SQL 语句:”[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 i am not add any null in productName but error org hibernate exception
  • 用户输入是否进入控制器或模型?

    现在我已经拆分了模型 但我的控制器和视图仍然组合在一个 12k 行文件中 我一直在寻求为此创建一个真正的 MVC 系统 拆分视图 但是在寻找要拆分的内容时 我注意到我的控制器正在执行大量可能属于模型的工作 例如 假设我有 if isset
  • IE7 一段时间后停止发出网络请求

    我们的 asp net 系统是一个更大系统的一部分 它是通过这个更大的系统从 javascript 启动的 该系统执行 window open 调用来打开一个新窗口 此外 身份验证数据等通过加密的查询字符串参数传递到我们的系统 当使用 IE
  • Windows - 使用 perl 监视目录中是否有新文件删除/创建

    寻找一种方法来监视目录中新文件的创建或删除 因此 如果我有一个文件夹 c temp 并且在其中复制 创建了 abc txt 我需要一个事件或其他内容 以便我可以拾取该文件然后处理它 另外 我想持续监控这个文件夹 我怎样才能做到这一点 我正在
  • 使用 AVAudioRecorder 看似随机的文件损坏(有时文件无法播放) - iOS

    在我目前正在开发的应用程序中 我或多或少遇到了障碍 在应用程序中 您可以进入一个视图 该视图在标准表格视图中列出所有本地保存的音频文件 从这里 您可以单击它们来播放它们 或者点击下面的录制按钮来制作新的录音 该录音随后会自动保存到应用程序沙
  • Android:Listview的弹跳到scrollview

    有什么方法可以将ListView的弹跳效果添加到常规滚动视图中吗 我所说的弹跳是指当您到达列表底部时类似橡皮筋的效果 在android中为listview添加效果反弹 Step 1 在com base view包中创建新文件BounceLi
  • 在 vaadin 8 中将文本复制到剪贴板

    我想问如何在 vaadin 8 java web 应用程序中正确地将一些文本复制到剪贴板 我找到了适用于 Chrome 和 IE 的解决方案 但不适用于 Firefox Firefox 总是提示 错误 document execComman
  • JqG​​rid 单元格中的选择框

    我试图让选择框位于特定的单元格中 我的复选框显示得很好 但选择框没有显示 list5 jqGrid datatype local width 100 height 100 colNames Universe1 Connect String1
  • 从更高的时间范围获取历史值

    我构建了一个自定义指标 并使用蜡烛顶部的点绘制了它们 当一个点与另一个点满足特定标准时 我会绘制一条连接它们的趋势线 这样可行 我想做的是从更高的时间范围增加这些线 因为我通常在 5m 上进行交易 意思是 如果每日时间范围内的这些点符合标准
  • jquery加载大数据

    我有一个返回数据的 Web 服务 数据集相当大 可能有 600 行 20 列 在 Jquery 代码中将此数据加载到 html 表中最快最有效的方法是什么 我尝试通过循环返回的数据并在字符串中创建表 DOM 来创建表 html 但循环部分非
  • 遵循 JSON-LD API 中的所有链接

    假设我想使用一个返回 JSON LD 的 API 并跟踪所有链接 我正在尝试Hydra API 演示 http www markus lanthaler com hydra api demo 但它应该适用于所有 JSON LD API 而不
  • ListView 中的 WPF ListView

    我确信我错过了一些简单 明显的东西 但我似乎无法在 ListView 中绑定 ListView 的数据
  • Java 中的 Thread.Sleep 替代方案

    有人告诉我使用Thread Sleep 有时 人们希望在同步方法的操作循环中设置一些时间间隔 这是一个糟糕的解决方案 另一方面 我有两个不同的线程 它们在程序运行期间处于活动状态 还有一个共享对象 当我在该共享对象中使用 Object wa
  • 是否有像 pygccxml 一样的 Python Clang 包装器来包装 GCC-XML?

    很长一段时间以来 我一直在使用 pygccxml 来解析和内省我的 C 源代码 它帮助我在构建过程中进行一些巧妙的代码生成 最近我读了很多关于 LLVM 堆栈的好处 特别是 LLVM Clang 解析器给 C 编译带来的好处 我现在想知道
  • 如何在 Debian 上升级 glibc?

    我听说我可以使用apt get install libc6 但我需要向 etc apt sources list 添加一些内容才能接收最新的 glibc 版本 我应该怎么办 我能够安装libc6 2 17 in Debian Wheezy通
  • 3D饼图:图例太大

    传说的问题太大了 当我改变cex的数量时 字体太小 盒子仍然很大 希望盒子和测试可以搭配 不会太小也不会太大 table lt data frame num c 90 26 28 39 98 countries c India Sri La
  • Parse.com:如何为 Fragment 内的 Parse ListView 添加搜索过滤器

    我正在尝试为选项卡片段内的 ListView 添加搜索过滤器 使用适配器从解析服务器调用数据 我的片段java文件如下 跑车 java import android os Bundle import android text Editabl
  • 如何使 Hibernate @Lock 注释适用于 Oracle DB?

    我偶然发现 Oracle DB 中锁定行的问题 锁的目的是防止多个事务从数据库读取数据 因为这些数据会影响新数据的生成 并且会在事务中发生更改 为了进行锁定 我将 Lock 注释放在 SpringData find 方法上 该方法检索参与事