Reputation: 88
I am using spring mvc 3.0 and hibernate. I am situation here as , I have inventory where user can add and remove items. For eg, total quantity =50. Now two users at a time wants to update inventory like 2 items removed by A and 4 Items removed by B. So, total quantity= 44. Now, how can I do this transaction, when both users try to update inventory at the same time?? If transaction is not maintained then the it would be like 50-2=48, and then 50-4=46.
Upvotes: 3
Views: 421
Reputation: 8985
You can use optimistic locking with versioning. Optimistic locking with versioning is enabled as soon as you add a or a property to a persistent class mapping. The property mapping in XML must be placed immediately after the identifier property mapping:
<class name="Item" table="ITEM">
<id .../>
<version name="version" access="field" column="OBJ_VERSION"/>
...
</class>
With this, when item is updated, the SQL will be:
update ITEM set INITIAL_PRICE='12.99', OBJ_VERSION=2
where ITEM_ID=123 and OBJ_VERSION=1
If another concurrent unit of work updated and committed the same row, the OBJ_VERSION column no longer contains the value 1, and the row isn’t updated. Hibernate checks the row count for this statement as returned by the JDBC driver—which in this case is the number of rows updated, zero—and throws a StaleObjectStateException.
If you don’t have version or timestamp columns, Hibernate can still perform automatic versioning, but only for objects that are retrieved and modified in the same persistence context (that is, the same Session). This alternative implementation of versioning checks the current database state against the unmodified values of persistent properties at the time the object was retrieved (or the last time the persistence context was flushed). You may enable this functionality by setting the optimistic-lock attribute on the class mapping:
<class name="Item" table="ITEM" optimistic-lock="all">
<id .../>
...
</class>
The following SQL is now executed to flush a modification of an Item instance: update ITEM set ITEM_PRICE='12.99' where ITEM_ID=123 and ITEM_PRICE='9.99' and ITEM_DESCRIPTION="An Item" and ... and SELLER_ID=45
In both cases, it's up to you to restart the second transaction or merge the update when you get the StaleObjectStateException. This case should be very rare, otherwise, you need to refactor to reduce the transaction scope in order to make it smaller and faster.
You can refer to the book "Java Persistent with Hibernate" by CHRISTIAN BAUER and GAVIN KING for more details. (Recommended)
EDIT: Ryan is right. I correct my answer.
Upvotes: -1
Reputation: 128949
Use a version property to ensure correct semantics. This is the topic of an entire section of the Hibernate reference guide: "Optimistic concurrency control"
Upvotes: 2