asp.net网站开发框架,有哪些可以做1元夺宝的网站,阿里云的国际网站建设,不会建网站JPA本质上提供了两种锁定机制#xff0c;以帮助同步对实体的访问。 两种机制都可以防止以下情况#xff1a;两个事务在不知道的情况下相互覆盖数据。 通过实体锁定#xff0c;我们通常希望通过2个并行事务来防止以下情况#xff1a; 亚当的事务读取数据X 芭芭拉的交易读… JPA本质上提供了两种锁定机制以帮助同步对实体的访问。 两种机制都可以防止以下情况两个事务在不知道的情况下相互覆盖数据。 通过实体锁定我们通常希望通过2个并行事务来防止以下情况 亚当的事务读取数据X 芭芭拉的交易读取数据X 亚当的交易会修改数据X并将其更改为XA 亚当的事务将数据写入XA 芭芭拉的交易修改了数据X并将其更改为XB 芭芭拉的交易写数据XB 结果亚当所做的更改完全被芭芭拉Barbara所取代甚至没有引起她的注意。 像这样的场景有时被称为脏读 。 显然理想的结果是Adam编写XA而Barbara被迫在编写XB之前检查XA更改。 乐观锁的工作原理 乐观锁定基于这样的假设冲突非常少见如果发生冲突则抛出错误是可以接受的并且比防止冲突更方便。 允许其中一项交易正确完成但其他任何交易都会例外回滚并且必须重新执行或丢弃。 通过乐观锁定亚当和芭芭拉可能出现以下情况 亚当的事务读取数据X 芭芭拉的交易读取数据X 亚当的交易会修改数据X并将其更改为XA 亚当的事务将数据写入XA 芭芭拉的交易修改了数据X并将其更改为XB Barbara的事务尝试写入数据XB但接收到并出错 芭芭拉需要读取数据XA或开始全新的交易 Barbara的事务修改了数据XA并将其更改为XAB Barbara的事务写入数据XAB 如您所见芭芭拉被迫审查亚当的更改如果她决定她可能会修改亚当的更改并保存合并更改。 最终数据包含亚当和巴巴拉的变化。 JPA完全控制乐观锁定。 它需要数据库表中的其他版本列。 它完全独立于用于存储关系数据的基础数据库引擎。 悲观锁定如何工作 对于某些人来说悲观锁定被认为是很自然的。 当事务需要修改实体可以由另一个事务并行修改时事务将发出锁定该实体的命令。 所有锁将保留到事务结束然后自动释放。 使用悲观锁情况可能是这样的 亚当的事务读取数据X 亚当的交易锁定X 芭芭拉的交易想要读取数据X但是等待X已被锁定 亚当的交易会修改数据X并将其更改为XA 亚当的事务将数据写入XA 芭芭拉的交易读取数据XA Barbara的事务修改了数据XA并将其更改为XAB Barbara的事务写入数据XAB 如我们所见Barbara再次被迫编写XAB其中也包含Adam所做的更改。 但是该解决方案与乐观方案完全不同–芭芭拉需要等待亚当的交易完成后才能读取数据。 此外我们需要在两个事务中手动发出锁定命令以使该方案起作用。 由于我们不确定亚当或芭芭拉首先要处理哪个事务因此两个事务都需要在修改数据之前先锁定数据。乐观锁定比悲观锁定需要更多的设置每个实体都需要使用version列但随后我们不需要记住在交易中发出锁。 JPA自动执行所有检查我们只需要处理可能的异常。 悲观锁定使用基础数据库提供的锁定机制锁定表中的现有记录。 JPA需要知道如何触发这些锁定并且某些数据库不完全支持。 甚至JPA规范都说不需要提供PESSIMISTIC_READ因为许多数据库仅支持WRITE锁 这是允许的以使用实施LockModeType.PESSIMISTIC_WRITE其中LockModeType.PESSIMISTIC_READ请求而不是相反。 JPA中可用锁类型的列表 首先我想说的是如果实体中提供了Version列则JPA会默认为此类实体打开乐观锁定。 您不需要发出任何锁定命令。 但是您可以随时使用以下一种锁类型发出锁 LockModeType.Optimistic 这确实是默认设置。 如ObjectDB所述通常将其忽略。 在我看来它只是存在的这样您就可以动态地计算锁定模式即使锁定最终是最优的也可以进一步传递它。 虽然用例不是很可能但是提供一个甚至引用默认值的选项也是一种很好的API设计。 示例Java LockModeType lockMode resolveLockMode();
A a em.find(A.class, 1, lockMode); LockModeType.OPTIMISTIC_FORCE_INCREMENT 这是很少使用的选项。 但是如果您想锁定另一个实体对这个实体的引用这可能是合理的。 换句话说即使您未修改某个实体您也希望锁定该实体的工作但是其他实体也可能相对于该实体而被修改。 例 我们有实体书和书架。 可以将Book添加到书架中但是book没有对其书架的引用。 锁定将书移动到书架上的操作是合理的这样一本书不会最终出现在两个书架中。 要锁定此操作仅锁定当前书架实体是不够的因为书还不必在书架上。 锁定所有目标书架也没有意义因为它们在不同交易中可能会有所不同。 唯一有意义的是锁定书本实体本身即使在我们这种情况下它没有被更改它不保留对其书架的引用。 LockModeType.PESSIMISTIC_READ 此模式类似于LockModeType.PESSIMISTIC_WRITE 但有一点不同在通过某种事务在同一实体上施加写锁定之前它不应阻止读取实体。 它还允许其他事务使用LockModeType.PESSIMISTIC_READ锁定。 WRITE和READ锁之间的区别在这里ObjectDB和这里OpenJPA都有很好的解释。 但是由于规范允许很多情况下它的行为类似于LockModeType.PESSIMISTIC_WRITE 许多提供程序并未单独实现它。 LockModeType.PESSIMISTIC_WRITE 这是LockModeType.PESSIMISTIC_READ的增强版本。 有了WRITE锁定后JPA借助数据库将阻止任何其他事务读取该实体而不仅仅是像READ锁定那样进行写入。 LockModeType.PESSIMISTIC_FORCE_INCREMENT 这是另一种很少使用的锁定模式。 但是这是您需要结合PESSIMISTIC和OPTIMISTIC机制的一种选择。 在以下情况下使用普通的PESSIMISTIC_WRITE可能会失败 事务A使用乐观锁定并读取实体E 事务B获得对实体E的WRITE锁定 事务B提交并释放E的锁 事务A更新E并提交 在第4步中如果版本B未被事务B递增则不会阻止A覆盖B的更改。锁定模式LockModeType.PESSIMISTIC_FORCE_INCREMENT将强制事务B更新版本号并导致事务A以OptimisticLockException失败即使B正在使用悲观的锁定。 为了发出某种类型的锁JPA提供了以下方法 一些EntityManager方法接受一个可选参数来指定锁定类型例如 find类entityClassObject primaryKeyLockModeType lockMode 查询还提供setLockModeLockModeType lockMode方法来锁定将由查询检索的所有实体 您可以在JPA中使用两种类型的锁定机制中的任何一种。 如果您使用类型PESSIMISTIC_FORCE_INCREMENT悲观锁也可以在必要时将它们混合使用。 要了解更多信息请阅读Vlad Mihalcea的优秀博客。 翻译自: https://www.javacodegeeks.com/2016/02/differences-jpa-entity-locking-modes.html