隔离级别与乐观锁定 - 休眠,JPA [英] Isolation Level vs Optimistic Locking-Hibernate , JPA

查看:87
本文介绍了隔离级别与乐观锁定 - 休眠,JPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,我希望确保在我尝试更新的对象上使用数据库级锁的并发性。我希望确保批量更改或其他用户或过程最终不会在数据库中引入不一致。



我发现隔离级别确保读取一致性和乐观锁定使用 @Version 字段可以确保数据以一致的状态写入。



我的问题不能保证与隔离级别一致吗?通过使我的任何事务更新记录Serializable(不考虑性能),我是否不确保事务处理和任何其他尝试更新或获取锁定的事务都会进行正确的锁定,否则此事务将失败?
我真的需要版本或时间戳管理吗?

解决方案

根据您选择的隔离级别,资源将被锁定,直到给定的事务提交或回滚 - 它可以锁定在整个表,行或sql块上。这是一个悲观的锁定,并且在运行事务时确保在数据库级别。另一方面,乐观锁定假定多个事务很少互相干扰,所以在这种方法中不需要锁定。这是一个应用程序端检查,它使用 @Version 属性来确定记录版本是否在获取和尝试更新之间发生了变化。



在Web应用程序中使用乐观锁定方法是合理的,因为大多数操作都跨越多个HTTP请求。通常你在一个请求中从数据库获取一些信息,并在另一个请求中更新它。保持事务处于开放状态并锁定数据库资源非常昂贵且不明智。这就是为什么我们假设没有人会使用我们正在处理的一组数据 - 它更便宜。如果假设发生错误并且版本在其他人的请求之间发生了变化,Hibernate将不会更新该行,并会抛出 OptimisticLockingException 。作为开发人员,您有责任管理这种情况。



简单的例子。在线拍卖服务 - 您正在看一个项目页面。你阅读它的描述和规范。所有这一切都需要5分钟。通过悲观锁定和一些隔离级别,您可以阻止其他用户访问此特定项目页面(或者甚至是所有项目!)。通过乐观锁定,每个人都可以访问它。阅读完您愿意出价的物品后,点击正确的按钮。如果有其他用户在观看此项目并更改其状态(所有者更改了其描述,其他人对其进行了出价),则您可能(取决于应用程序实施)在应用程序接受您的出价之前了解有关更改,因为您的版本数据库中存在的版本不一样。



希望能为您澄清一些事情。


I have a web application where I want to ensure concurrency with a DB level lock on the object I am trying to update. I want to make sure that a batch change or another user or process may not end up introducing inconsistency in the DB.

I see that Isolation levels ensure read consistency and optimistic lock with @Version field can ensure data is written with a consistent state.

My question is can't we ensure consistency with isolation level only? By making my any transaction that updates the record Serializable(not considering performance), will I not ensure that a proper lock is taken by the transaction and any other transaction trying to update or acquire lock or this transaction will fail? Do I really need version or timestamp management for this?

解决方案

Depending on isolation level you've chosen, specific resource is going to be locked until given transaction commits or rollback - it can be lock on a whole table, row or block of sql. It's a pessimistic locking and it's ensured on database level when running a transaction.

Optimistic locking on the other hand assumes that multiple transactions rarely interfere with each other so no locks are required in this approach. It is a application-side check that uses @Version attribute in order to establish whether version of a record has changed between fetching and attempting to update it.

It is reasonable to use optimistic locking approach in web applications as most of operations span through multiple HTTP request. Usually you fetch some information from database in one request, and update it in another. It would be very expensive and unwise to keep transactions open with lock on database resources that long. That's why we assume that nobody is going to use set of data we're working on - it's cheaper. If the assumption happens to be wrong and version has changed in between requests by someone else, Hibernate won't update the row and will throw OptimisticLockingException. As a developer, you are responsible for managing this situation.

Simple example. Online auctions service - you're watching an item page. You read its description and specification. All of it takes, let's say, 5 minutes. With pessimistic locking and some isolation levels you'd block other users from this particular item page (or all of the items even!). With optimistic locking everybody can access it. After reading about the item you're willing to bid on it so you click the proper button. If any other of users watching this item and change its state (owner changed its description, someone other bid on it) in the meantime you will probably (depending on app implementation) be informed about the changes before application will accept your bid because version you've got is not the same as version persisted in database.

Hope that clarifies a few things for you.

这篇关于隔离级别与乐观锁定 - 休眠,JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆