我正在使用spring mvc 3.0和hibernate。我在这里的情况是,我有用户可以添加和删除项目的库存。例如,总数量= 50。现在两个用户一次想要更新库存,例如A删除的2个项目和B删除的4个项目。因此,总数量= 44.现在,当两个用户同时尝试更新库存时,我该如何进行此交易??如果没有维持交易,那么它将像50-2 = 48,然后50-4 = 46。
答案 0 :(得分:2)
使用version property确保正确的语义。这是Hibernate参考指南的整个部分的主题:"Optimistic concurrency control"
答案 1 :(得分:-1)
您可以对版本控制使用乐观锁定。 添加a后,即可启用带版本控制的乐观锁定 或持久类映射的属性。 XML中的属性映射必须紧跟在标识符属性映射之后:
<class name="Item" table="ITEM">
<id .../>
<version name="version" access="field" column="OBJ_VERSION"/>
...
</class>
有了这个,当项目更新时,SQL将是:
update ITEM set INITIAL_PRICE='12.99', OBJ_VERSION=2
where ITEM_ID=123 and OBJ_VERSION=1
如果另一个并发工作单元更新并提交了同一行,那么 OBJ_VERSION列不再包含值1,并且行未更新。 Hibernate检查JDBC返回的此语句的行计数 驱动程序 - 在这种情况下是更新的行数,零 - 并抛出a StaleObjectStateException。
如果您没有版本或时间戳列,Hibernate仍然可以自动执行 版本控制,但仅适用于在同一版本中检索和修改的对象 持久化上下文(即同一个Session)。 版本控制的这种替代实现检查当前数据库 状态反对对象时持久属性的未修改值 已检索(或上次刷新持久性上下文时)。你可以 通过在类上设置optimistic-lock属性来启用此功能 映射:
<class name="Item" table="ITEM" optimistic-lock="all">
<id .../>
...
</class>
现在执行以下SQL来刷新Item实例的修改: 更新ITEM集ITEM_PRICE = '12 .99' 其中ITEM_ID = 123 和ITEM_PRICE ='9.99' 和ITEM_DESCRIPTION =“一个项目” 和...... 和SELLER_ID = 45
在这两种情况下,您都可以在获得StaleObjectStateException时重新启动第二个事务或合并更新。这种情况应该非常少见,否则,您需要重构以减少事务范围,以使其更小更快。
有关详细信息,请参阅CHRISTIAN BAUER和GAVIN KING的“Java Persistent with Hibernate”一书。 (推荐)
编辑: Ryan是对的。我纠正了我的答案。