根据您选择的隔离级别,特定资源将被锁定,直到给定事务提交或回滚为止-它可以锁定在整个表,行或sql块上。这是一种悲观的锁定,并且在运行事务时可以在数据库级别上确保。
另一方面,乐观锁定假定多个事务很少相互干扰,因此在此方法中不需要锁定。这是应用程序侧检查,使用@Version
属性来确定记录的版本在获取和尝试更新之间是否已更改。
在Web应用程序中使用乐观锁定方法是合理的,因为大多数操作都跨越多个HTTP请求。通常,您在一个请求中从数据库中获取一些信息,然后在另一个请求中对其进行更新。长时间保持数据库资源锁定来保持事务打开是非常昂贵且不明智的。这就是为什么我们假设没有人会使用我们正在处理的数据集的原因-它更便宜。如果假设碰巧是错误的,并且其他人在两次请求之间更改了版本,则Hibernate将不会更新该行,而是会抛出OptimisticLockingException
。作为开发人员,您有责任管理这种情况。
简单的例子。在线拍卖服务-您正在观看商品页面。您阅读了其说明和规范。假设所有过程都需要5分钟。通过悲观的锁定和某些隔离级别,您可以阻止其他用户访问此特定项目页面(甚至所有项目!)。通过乐观锁定,每个人都可以访问它。在阅读了有关该项目的内容后,您愿意出价,因此您单击适当的按钮。如果与此同时有其他用户观看此项目并更改其状态(所有者更改了其描述,其他人对其进行了出价),则您可能会(取决于应用程序的实施情况)被告知有关更改,然后应用程序才会接受您的出价,因为版本已经与数据库中保留的版本不同。
希望能为您澄清一些事情。
除非我们正在谈论一些小型的、独立的 Web 应用程序(仅在数据库上运行的应用程序),否则使所有事务都可序列化意味着对您的设计有很大的信心,而不是考虑到它的事实可能不是唯一访问该特定数据库的应用程序。
在我看来,结合可序列化隔离级别,或者换句话说,悲观锁,应该很好地通过决策和应用:
根据我的经验,在大多数情况下,仅使用乐观锁将是最有益的决定,因为频繁的并发修改通常只发生在一小部分情况下。乐观锁定肯定还可以帮助其他应用程序运行得更快(不要只考虑自己!)。
因此,当我们采用悲观-乐观锁定策略系列时,我认为事实更接近于带有可串行化风格的乐观锁定。
我真的无法在这里引用任何内容,因为答案是基于我在许多复杂的 Web 项目中的个人经验以及我准备 JPA 证书时的笔记。
希望有帮助。
归档时间: |
|
查看次数: |
2462 次 |
最近记录: |