java - 如何使用 JPA 和 Hibernate 避免产品销售的竞争条件

标签 java hibernate jpa concurrency transactions

我正在使用 Java Spring 框架和 Hibernate。我正在做一个电子商务网络应用程序,公共(public)用户可以从该网络应用程序购买产品。每个产品都会有一个数量计数。

问题

我想防止两个并发用户购买同一产品并留下数量值 1 的情况。在这种情况下,只有第一个用户应该购买该产品,而第二个用户应该收到“无库存”消息。

工作流程

我打算减少数量计数,然后将购买信息发送到支付网关。如果支付网关遇到支付问题,我会增加数量计数。在购买信息发送到支付网关之前,锁定将被释放。

所以我的问题是,

1) 我想确认 this answer关于悲观锁定确实有助于解决我的问题。

2) 我的工作流程还好吗?有更好的方法吗?

最佳答案

您还可以使用 optimistic locking并防止可能lost updates .

使用乐观锁定,如果两个用户加载了数量为 1 的同一个实体,并且一个用户刚刚进行了购买并减少了数量计数器,那么第二个用户将不会能够更新产品实体,因为他的 Product 版本与读取实体时在数据库中找到的版本不匹配。

如果实体 version 发生变化,则尝试匹配旧 versionUPDATE 语句将返回 0PreparedStatementexecuteUpdate 方法被调用时。那时 Hibernate 将检测陈旧状态情况并抛出 OptimisticLockException

Spring TransactionInterceptor 将捕获 OptimisticLockException,并且关联的事务将被回滚。

乐观锁定方法比悲观锁定具有更好的扩展性,并且它也适用于多请求逻辑事务。

关于java - 如何使用 JPA 和 Hibernate 避免产品销售的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29574630/

相关文章:

java - 创建类的新对象后获取 NPE

JavaFX |英特尔lij : Create elevated application

java - 每次更新时移动 JLabel 的位置

java - 理解 hibernate 中的 NonUniqueObjectException

java - 异常 : "No adapter for handler. Does your handler implement a supported interface like controller?"

java - 用笑脸围绕一根绳子

java - hibernate 更新一对多项目集

java - 如何将文本 JPQL JPA 查询转换为条件查询?

mysql - Hibernate CURRENT_TIMESTAMP 和 MySQL 中的多实体事务

java - Kotlin 数据类 equals() 方法是否可以在不进一步修改的情况下与 JPA 一起使用?