何时使用JPA锁定?

huangapple go评论80阅读模式
英文:

When to use JPA locking?

问题

我正在开发一个简单的Spring Boot CRUD应用程序,使用JPA管理数据库中的产品。该应用程序在我的测试中表现如预期,可以创建、读取、更新和删除产品。现在我正在考虑这个应用程序在并发环境中的性能表现。

阅读 https://www.baeldung.com/jpa-optimistic-locking,该文档描述了如何以“有效且更重要的是,无误”的方式处理“多个事务”。但是这不是由Spring Boot框架处理吗?我过去曾遇到过CRUD应用程序,并没有遇到过明确实现锁定的情况。我认为任何数据库更新都是线程安全的,不需要显式实现锁定,但这并不总是正确的吗?

我是否应该使用锁定来计算产品库存,例如?所以,如果我有3个产品,并且有3个GET请求被调用来分别读取1号、2号和3号产品,存在这样一个风险,即其中一个线程将访问数据库尚未足够时间更新以指示该产品不再可用,因为其他线程已经耗尽了库存?

英文:

I'm developing a simple Spring Boot CRUD application using JPA that manages products in a DB. This application behaves as expected in my testing in that products can be created, read, updated and deleted. Now I'm considering how this application will perform in a concurrent environment.

Reading https://www.baeldung.com/jpa-optimistic-locking which describes handling "multiple transactions in an effective and most importantly, error-proof way." But is this not handled by the Spring Boot framework? I've encountered CRUD apps in the past and never encountered locking being explicitly implemented. I assumed that any DB updates are thread-safe and locking is not required to be implemented explicitly but is this not always true?

Should I use locking to calculate for example product inventory? So if I have 3 products and 3 GET requests are invoked to read 1,2 and 3 product respectively there is a risk that one of the threads will access a product that the DB has not updated insufficient time to indicate that the product is no longer available as other threads have exhausted the inventory?

答案1

得分: 3

乐观锁定有助于防止您在具有旧实体信息的情况下进行更改。

想象以下情景:

您有一个产品实体,该产品有采购价和销售价。

假设一个线程从数据库加载实体,购买价格为10美元,销售价格为12美元。

代码将销售价格调整为15美元,但在将此更改提交到数据库之前,另一个线程也正在修改该实体。

另一个线程调整了购买价格,并将其增加到了20美元,并且此更改已经提交到数据库。

我相当确信,如果购买价格为20美元,您不会想将销售价格设置为15美元。

通过乐观锁定,框架(如Hibernate)会检查待保存的实体是否与从数据库加载时的状态相同。否则,它将抛出OptimisticLockingException异常。
如果购买价格仍为10美元,则将销售价格更改为15美元是可以的。但是,如果购买价格在此期间发生了变化,乐观锁定将帮助您在旧信息上不设置新的销售价格(在本例中,购买价格为10美元)。

英文:

Optimistic locking helps to prevent that you change something having old information of the entity.

Imagine the following scenario:

You have an Product entity and this product a purchase and a selling price.

Imagine one thread loads the enitity from the database and the purchase price is 10 dollar and the selling price is 12 dollar.

The code adjusts the selling price to 15 dollar but before this change is commited to the database another thread is also modifying the entity.

The other thread adjusted the purchase price and increased it to 20 dollar and this change is already committed to the database.

I'm pretty sure you do not want to set the selling price to 15 dollar if the purchase price is 20 dollar.

With optimistic locking the framework (i.e. hiberate) checks whether the entity that shall be saved is in the same state that it was when it has been loaded from the database. Otherwise it will throw a OptimisticLockingException.
If the purchase price is still 10 dollar changing the selling price to 15 dollar is fine. But if the purchase price has changed somehow in the meantime the optimistic locking helps you to not set a new selling price on outdated information (in this case that the purchase price is 10 dollar)

huangapple
  • 本文由 发表于 2020年9月23日 02:16:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64015518.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定