我对JPA非常陌生,我读过关于JPA2.0中锁定模式的这文章,这给我留下了一个关于LockModeType.OPTIMISTIC_FORCE_INCREMENT的问题。
下面是一个带有本文示例的图像:http://i.stack.imgur.com/dFjhZ.jpg
到目前为止,我理解只有当我对实体A的更新取决于刚刚读取的另一个实体B的状态时,事务T1中的显式乐观锁定才是必要的。
我还了解到,使用OPTIMISTIC_FORCE_INCREMENT的锁会导致B更新它的version属性,这将导致在所有试图更新B并在发出锁之前读取它的事务中产生OptimisticLockException (即使用旧的版本值)。
我的问题是:,如果另一个事务T2在B版本增加、更改B并在T1提交之前完成之后立即启动,会发生什么?
据我所知,T1应该得到一个OptimisticLockException。如果是这样的话,这个锁有什么意义,因为它只是稍微减少了T1的易受攻击的时间窗口?这意味着:如果我想确保在T1完成之前B不会改变,我需要一个悲观的锁,对吗?
谢谢你事先向我说明了这一点:)
发布于 2013-03-09 00:49:22
您的示例问题突出了为什么这被称为“乐观”锁定。它并不完美,但如果它能满足现实世界中的大量情况,而且它使用的资源(包括时间)比硬锁少得多。
当使用这种类型的锁定时,您将以性能为交换,并且通常是改进的使用能力,您打赌您的事务在大多数情况下都能正常工作,并且您确信,在不工作的情况下,您将得到通知(异常将被抛出),然后您可以后退一步,“做正确的事情”:再试一次,放弃,但是,您选择处理异常。
在需要某种级别锁定的高性能事务系统中,悲观锁可能非常不合适,但它们碰撞的可能性很小:数百万xTunes用户中有多少人更改了名称以保护无辜.“订单”(更新)在任何时候,有多少都是从同一个帐户订购(更新)?
发布于 2016-10-25 06:44:17
如果另一个事务T2在B版本增加、更改B并在T1提交之前完成之后立即启动,会发生什么?
无论您要使用什么RDBMS,即使使用MVCC (多版本并发控制)或2PL (两阶段锁定),当您更改表行时,都会获得独占锁,并且只在当前运行的事务结束时才释放锁(提交或回滚)。
因此,一旦增加了B的版本,在提交事务之前,任何其他事务都不能更改该记录。
还值得一提的是OPTIMISTIC_FORCE_INCREMENT和PESIMISTIC_FORCE_INCREMENT之间的区别。OPTIMISTIC_FORCE_INCREMENT在事务结束时执行版本增量,而PESIMISTIC_FORCE_INCREMENT则会立即提高版本。
如果在该特定实体上存在大量争用,那么PESIMISTIC_FORCE_INCREMENT更有吸引力,因为一旦您获得了锁,就不允许其他事务修改该记录,并且您的事务不会因为乐观的版本错配失败而回滚。
https://stackoverflow.com/questions/15293275
复制相似问题