我正在阅读有关jpa锁定的文章。链接:https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and
在关于乐观锁(READ)的部分中,作者具有代码段,该代码段表示由于异常而使事务2回滚。基于代码段,事务2在事务1修改dep的名称之前获取了对dep的锁定。如果我正确地理解了学校的演讲,从获得锁(在本文中为em)到释放锁(在本文中为tx2.commit)到采取行动(将员工提高10%,在本文中)是原子的,这意味着该部门的名称不能设置为“ MarketEng”,因此该员工的工资提高了10%。在提交tx2之后,它将释放锁,并且dep的名称最终将设置为“ MarketEng”。因此,不会回滚任何事务,这是线程安全的。
我理解正确吗?如果没有,请向我解释作者“ e1得到他应得的加薪”的意思。
乐观锁定有点用词不当-没有实际的锁定。您所描述的行为em.lock
是悲观锁,在tx2中该行为将阻止tx1中的更新。在JPA中,悲观锁转换为select .. for update
DB中的行级锁。乐观锁则不然。
乐观锁定改为使用计数器在对象更新时进行通信,或验证是否发生了更新。写操作总是使计数器递增。使用LockMode.OPTIMISTIC进行的读取将在提交时检查计数器,如果值已更改,则失败并发生异常或回滚。
乐观锁定的要点是,您对实际在同一对象实例上发生的此类冲突很少感到“乐观”,因此,冒着提交失败的风险要比使用实际的行级锁定来减慢所有操作的风险更好,而不必担心僵局。
在此特定示例中,有两个事务同时运行:
但是,此示例还是有缺陷的,因为从业务或用户角度来看的影响与直觉不符-如果tx1只是在提交tx2之后才开始,则部门名称在员工加薪后会立即更改。如果名称稍早更改一秒钟,为什么有关系?
我想使用的比喻是版本控制系统。大多数版本控制系统(例如svn和git)都使用某种形式的乐观锁定。允许两个人同时开始处理同一个文件,但是当您尝试提交别人首先提交的文件时,会出现错误。其他版本控制系统,例如Visual SourceSafe(至少是我上次使用它)使用悲观锁定,在这种情况下,您必须签出文件进行编辑,而签出是互斥锁-没有其他人可以签出同一文件以进行锁定编辑,直到您提交。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句