jpa 关联实体的关联实体

JPA本质上提供了两种锁定机制,以帮助同步对实体的访问。 两种机制都可以防止以下情况:两个事务在不知道的情况下相互覆盖数据。

通过实体锁定,我们通常希望通过2个并行事务来防止以下情况:

  1. 亚当的事务读取数据X
  2. 芭芭拉的交易读取数据X
  3. 亚当的交易会修改数据X,并将其更改为XA
  4. 亚当的事务将数据写入XA
  5. 芭芭拉的交易修改了数据X并将其更改为XB
  6. 芭芭拉的交易将数据写入XB

结果,亚当所做的更改完全被芭芭拉(Barbara)所取代,甚至没有引起她的注意。 像这样的场景有时称为脏读 。 显然,理想的结果是Adam编写XA,而Barbara被迫在编写XB之前检查XA更改。

乐观锁的工作原理

乐观锁定基于这样的假设:冲突非常少见;如果发生冲突,则抛出错误是可以接受的,并且比防止冲突更方便。 允许其中一项交易正确完成,但其他任何交易都会例外回滚,并且必须重新执行或丢弃。

通过乐观锁定,亚当和芭芭拉可能出现以下情况:

  1. 亚当的事务读取数据X
  2. 芭芭拉的交易读取数据X
  3. 亚当的交易会修改数据X,并将其更改为XA
  4. 亚当的事务将数据写入XA
  5. 芭芭拉的交易修改了数据X并将其更改为XB
  6. Barbara的事务尝试写入数据XB,但接收到并出错
  7. 芭芭拉需要读取数据XA(或开始全新的交易)
  8. Barbara的事务修改了数据XA并将其更改为XAB
  9. Barbara的事务写入数据XAB

如您所见,芭芭拉被迫审查亚当的更改,如果她决定,她可能会修改亚当的更改并保存(合并更改)。 最终数据包含亚当和巴巴拉的变化。

JPA完全控制乐观锁定。 它需要数据库表中的其他版本列。 它完全独立于用于存储关系数据的基础数据库引擎。

悲观锁定如何工作

对于某些人来说,悲观锁定被认为是很自然的。 当事务需要修改实体(可以由另一事务并行修改)时,事务将发出锁定该实体的命令。 所有锁将保留到交易结束,然后它们将自动释放。

使用悲观锁,情况可能是这样的:

  1. 亚当的事务读取数据X
  2. 亚当的交易锁定X
  3. 芭芭拉的交易想要读取数据X,但是等待X已被锁定
  4. 亚当的交易会修改数据X,并将其更改为XA
  5. 亚当的事务将数据写入XA
  6. 芭芭拉的交易读取数据XA
  7. Barbara的事务修改了数据XA并将其更改为XAB
  8. Barbara的事务写入数据XAB

如我们所见,Barbara再次被迫编写XAB,其中也包含Adam所做的更改。 但是,该解决方案与乐观方案完全不同–芭芭拉需要等待亚当的交易完成,甚至无法读取数据。 此外,我们需要在两个事务中手动发出锁定命令,以使场景正常工作。 (由于我们不确定首先要处理的是Adam还是Barbara事务,因此两个事务都需要在修改数据之前先锁定数据。)与悲观锁定相比,乐观锁定需要更多的设置,每个实体都需要使用version列,但是随后我们不需要记住在交易中发出锁。 JPA自动执行所有检查,我们只需要处理可能的异常。

悲观锁定使用基础数据库提供的锁定机制锁定表中的现有记录。 JPA需要知道如何触发这些锁,并且某些数据库不完全支持。

甚至JPA规范都说,不需要提供PESSIMISTIC_READ(因为许多数据库仅支持WRITE锁):

这是允许的,以使用实施LockModeType.PESSIMISTIC_WRITE其中LockModeType.PESSIMISTIC_READ请求,而不是相反。

JPA中可用锁类型的列表

首先,我想说的是,如果实体中提供了@Version列,则JPA会默认为此类实体打开乐观锁定。 您不需要发出任何锁定命令。 但是,您随时可以使用以下一种锁类型发出锁:

  1. LockModeType.Optimistic

    • 这确实是默认设置。 如ObjectDB所述,通常将其忽略。 在我看来,它只是存在的,因此您可以动态地计算锁定模式,即使锁定最终是最优的,也可以进一步传递它。 虽然用例不是很可能,但是提供一个甚至引用默认值的选项也是一种很好的API设计。
    • 示例:Java
      LockModeType lockMode = resolveLockMode();
      A a = em.find(A.class, 1, lockMode);
  2. LockModeType.OPTIMISTIC_FORCE_INCREMENT
    • 这是很少使用的选项。 但是,如果您想锁定另一个实体对这个实体的引用,这可能是合理的。 换句话说,即使您未修改某个实体,您也希望锁定该实体的工作,但是其他实体也可能相对于该实体而被修改。
    • 例:
      • 我们有实体书架。 可以将Book添加到书架中,但是book没有对其书架的引用。 锁定将书移动到书架上的操作是合理的,这样一本书不会最终出现在两个书架中。 要锁定此动作,仅锁定当前书架实体是不够的,因为书还不必在书架上。 锁定所有目标书架也没有意义,因为它们在不同交易中可能会有所不同。 唯一有意义的事情是锁定书本实体本身,即使在我们这种情况下它没有被更改(它不保留对其书架的引用)。
  3. LockModeType.PESSIMISTIC_READ
    • 此模式类似于LockModeType.PESSIMISTIC_WRITE ,但有一点不同:在通过某种事务在同一实体上施加写锁定之前,它不应阻止读取实体。 它还允许使用LockModeType.PESSIMISTIC_READ锁定其他事务。 在这里(ObjectDB)和这里(OpenJPA)很好地解释了 WRITE和READ锁之间的差异。 但是,通常情况下,它的行为就像LockModeType.PESSIMISTIC_WRITE ,因为规范允许这样做,而且许多提供程序没有单独实现它。
  4. LockModeType.PESSIMISTIC_WRITE
    • 这是LockModeType.PESSIMISTIC_READ的增强版本。 有了WRITE锁定后,JPA借助数据库将阻止任何其他事务读取该实体,而不仅仅是像READ锁定那样进行写入。
  5. LockModeType.PESSIMISTIC_FORCE_INCREMENT
    • 这是另一种很少使用的锁定模式。 但是,这是您需要结合PESSIMISTICOPTIMISTIC机制的一种选择。 在以下情况下,使用普通的PESSIMISTIC_WRITE将会失败:

      1. 事务A使用乐观锁定并读取实体E
      2. 事务B获得对实体E的WRITE锁定
      3. 事务B提交并释放E的锁
      4. 事务A更新E并提交
    • 在第4步中,如果版本B未被事务B递增,则不会阻止A覆盖B的更改。锁定模式LockModeType.PESSIMISTIC_FORCE_INCREMENT将强制事务B更新版本号,并导致事务A以OptimisticLockException失败,即使B正在使用悲观的锁定。

为了发出某种类型的锁,JPA提供了以下手段:

  • 一些EntityManager方法接受一个可选参数来指定锁定类型,例如:

    • find(类entityClass,Object primaryKey,LockModeType lockMode)
  • 查询还提供setLockMode(LockModeType lockMode)方法来锁定将由查询检索的所有实体

您可以在JPA中使用两种类型的锁定机制中的任何一种。 如果您使用类型PESSIMISTIC_FORCE_INCREMENT悲观锁,也可以在必要时将它们混合使用。

  • 要了解更多信息,请阅读Vlad Mihalcea的优秀博客。

翻译自: https://www.javacodegeeks.com/2016/02/differences-jpa-entity-locking-modes.html

jpa 关联实体的关联实体

jpa 关联实体的关联实体_JPA实体锁定模式的差异相关推荐

  1. JPA实体锁定模式的差异

    JPA本质上提供了两种锁定机制,以帮助同步对实体的访问. 两种机制都可以防止以下情况:两个事务在不知道的情况下相互覆盖数据. 通过实体锁定,我们通常希望通过2个并行事务来防止以下情况: 亚当的事务读取 ...

  2. 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明...

    一.首先了解下Entity Framework 自动关联查询: Entity Framework 自动关联查询,有三种方法:Lazy Loading(延迟加载),Eager Loading(预先加载) ...

  3. jpa 实体图查询_JPA实体图

    jpa 实体图查询 JPA 2.1的最新功能之一是可以使用实体图指定获取计划. 这很有用,因为它允许您自定义使用查询或查找操作检索的数据. 在使用中大型应用程序时,通常以不同的方式显示来自同一实体的数 ...

  4. java 实体类 临时注解_JPA:Java持久层API--配置流程

    一.JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...

  5. JPA 关联表添加关联条件@Where、@WhereJoinTable()

    JPA 关联表添加关联条件,当我其中一个表的数据状态发送改变,不是业务上所需要的,这时实体查询还是会带出关联数据,所以我们需要处理这部分数据:第一种方式:删除中间表对应数据:第二种添加关联条件,按条件 ...

  6. Spring Data JPA 实现多表关联查询

    原文链接:https://blog.csdn.net/johnf_nash/article/details/80587204 多表查询在spring data jpa中有两种实现方式,第一种是利用hi ...

  7. 【SpringBoot Data JPA】多表关联查询

    SpringBoot Data JPA 多表关联查询 前言 一.数据库架构设计 1.1 数据表结构 2.2 建立数据库表: 二.SpringBoot整合JPA多表查询 2.1 环境配置 2.2 建立数 ...

  8. [NewLife.XCode]实体工厂(拦截处理实体操作)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  9. mysql数据库实体_关系型数据库中实体之间的关系

    关系型数据库实体间有三种关联关系:一对一,一对多,多对多. 一对一关系(1:1): 如果实体集(表)A 中的每一个实休(就是每行记录),在实体集B中只有一条数据与它对应, 反之实体集B 中的每一个实体 ...

最新文章

  1. 两亿多用户,六大业务场景,知乎AI用户模型服务性能如何优化?
  2. 设计模式系列8--策略模式
  3. UML博客建模--用例图
  4. 直接拿来用!最火的Android开源项目(完结篇)
  5. javascript 迁移 typescript 实践
  6. java class 关键字_java关键字及其作用
  7. 广东48.6万人资产超600万 华东超600万人群最多
  8. 基于PCA和贝叶斯决策对CIFAR-10数据图像分类
  9. 如何把程序挂在远端服务器python_Pycharm连接远程服务器并实现远程调试的实现...
  10. web端项目管理/工程项目劳务资源管理系统/考勤审批/人员招聘/企业管理系统/工资管理/入职管理/组织结构/财务管理/大数据指挥中心/劳务系统/岗位工种/智慧工程监管/劳务app原型/axure原型
  11. Scala基础 - 函数和方法的区别
  12. ceres-solver库编译说明
  13. 【转】Linux內核驅動之GPIO子系統(一)GPIO的使用 _蝸牛
  14. 电路——I/O口定时翻转电平驱动蜂鸣器注意事项
  15. 如何注册苹果开发者账号
  16. 数学分析教程(科大)——2.1笔记+习题
  17. 支撑起SNS的六度分隔理论和150法则
  18. (php毕业设计)基于php健身俱乐部管理系统源码
  19. 如何与别人解释云计算是什么意思?
  20. 对于因果模型的常见评估函数:SHD 和 FDR

热门文章

  1. P4774-[NOI2018]屠龙勇士【EXCRT】
  2. 欢乐纪中A组周六赛【2019.5.18】
  3. OJ4008-糖果【各种dp之3】
  4. E. Pattern Matching(题意理解+拓扑排序)
  5. 【SPFA】最优贸易(luogu 1073)
  6. 18、java中的泛型
  7. 41、java应用占用cpu过高原因分析
  8. Sentinel(三)之如何使用
  9. 详解proxy_pass、upstream与resolver
  10. Java启动参数与内存调优一些学习笔记