在Hibernate中将属性值减1

时间:2013-11-15 11:49:16

标签: java mysql hibernate orm

我的 MySQL 中有一个 InnoDB表,它存储产品的当前库存,每当产品销售时(总是按单位,即始终为-1) ,股票必须通过这样做来更新,比方说:

UPDATE product_stock SET current_stock = current_stock -1 WHERE product_id = ?;

现在,我正在使用 Hibernate ,所以我通过将currentStock属性的值设置为“currentValue -1”来更新对象ProductStock,如下所示:

instance.setCurrentStock(instance.getCurrentStock()-1);
...
session.saveOrUpdate(instance);

现在,我正在使用事务来提交更改,但是我不确定在同时进行多次销售时hibernate会做什么,而且我无法成功复制我的问题想想会发生,也就是说,current_stock不会保存为current_stock -1,而是保存为我设置为对象实例属性的值。 例如,我有100个,两个交易同时开始销售产品,两个交易都在代码中

instance.setCurrentStock(instance.getCurrentStock()-1); 

将股票设置为99,然后交易结束,当前股票保存到99,应该是98,我是对吗?

问题:应该/必须使用HQL语句将库存直接更新为-1而不是从代码更新对象的值吗?

更新

我能够通过负载测试应用程序来复制错误,许多用户同时进行购买,但实际发生的事情并不是Hibernate正在保存库存错误,发生了什么是死锁在数据库级别。我们目前正在努力,所给出的答案非常有帮助。

我现在面临的问题是处理锁可能会很棘手,因为current_stock表及其某些行可能同时有许多读取和多次写入。我将发布进度并希望最终的解决方案

2 个答案:

答案 0 :(得分:1)

你必须尝试hibernate的Optimistic-lock属性。

 <class name="pojofile" table="tablename" optimistic-lock="">      


</class>

你也可以看到这个链接

Optimistic Locking in Hibernate by default

答案 1 :(得分:1)

我认为你的选择是:

  1. 使用HQL直接在数据库中建议和减少库存水平。这样做的缺点是,如果有多个同时进行的交易,则无法保证库存水平不会低于零!
  2. 使用Hibernate的乐观或悲观锁定 - 这个here的文档中有很多信息。
  3. 确保数据库更新只能从单个线程发生,因此事务不能重叠。