在spring mvc和hibernate中进行事务

时间:2012-05-01 05:10:32

标签: hibernate spring-mvc

我正在使用spring mvc 3.0和hibernate。我在这里的情况是,我有用户可以添加和删除项目的库存。例如,总数量= 50。现在两个用户一次想要更新库存,例如A删除的2个项目和B删除的4个项目。因此,总数量= 44.现在,当两个用户同时尝试更新库存时,我该如何进行此交易??如果没有维持交易,那么它将像50-2 = 48,然后50-4 = 46。

2 个答案:

答案 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是对的。我纠正了我的答案。