留言板

Question about concurrent updates on the same entity

Michal Cisty,修改在13 年前。

Question about concurrent updates on the same entity

New Member 帖子: 5 加入日期: 11-1-12 最近的帖子
Hello guys.

I would like to ask how to handle a scenario where two users are modifying the same persistent object at the same time.

I am using Liferay 6.0.5 and Service Builder to create the persistent layer of my portlet.

At the moment, when two users are editing the same object, the second user that clicks on "Save" overwrites the changes made by the first user.

I would like a behavior where the first user to click on "Save" would have his changes persisted, whereas the second user, when attempting to save his changes, would see a warning that he is already seeing old data and therefore must refresh.

Could you please suggest how to achieve something like this?

Thanks very much for help.
Michal
thumbnail
jelmer kuperus,修改在13 年前。

RE: Question about concurrent updates on the same entity

Liferay Legend 帖子: 1191 加入日期: 10-3-10 最近的帖子
What you describe would be implemented via hibernate optimistic locking. Unfortunately it does not look like servicebuilder supports it
thumbnail
Minhchau Dang,修改在13 年前。

RE: Question about concurrent updates on the same entity

Liferay Master 帖子: 598 加入日期: 07-10-22 最近的帖子
Michal Cisty:
Could you please suggest how to achieve something like this?

You would probably use the notion of versions (which is all that Hibernate optimistic locking does).

Essentially, you add a 'version' column to your entity. When rendering the object in a form, you include the value for 'version'. Before you persist the entity to the database, you verify that the 'version' value in the database is the same as what's submitted in the form. If they're different, you notify the user that it's already been modified.

If you need to merge the values for the user (possibly to help guide them on what the data needs to be), you would need to add some sort of version history as well (which doesn't necessarily have to be a SQL table; it could easily be a NoSQL repository or a list of expando attributes) that keeps track of the contents of each 'version' of the entity.

Depending on the nature of your data, you could steal ideas from version control systems (like SVN or Mercurial, which I believe both do it in this fashion) and just store diffs, though that is likely to be a lot more complex than what you wanted.
thumbnail
jelmer kuperus,修改在13 年前。

RE: Question about concurrent updates on the same entity

Liferay Legend 帖子: 1191 加入日期: 10-3-10 最近的帖子
Hibernate is a bit more clever than that. The sql it generates for updates of entities that have version columns looks something like this

update table set ..... where id = ? and version = ?

After it executes the statement it checks the number of rows affected. If it's 0 there was a conflict.

This leaves no room for race conditions. What you are suggesting is inherently flawed because just after you read the value from the database to check the version, someone else can have updated the record.

But admittedly this would be rare
Michal Cisty,修改在13 年前。

RE: Question about concurrent updates on the same entity

New Member 帖子: 5 加入日期: 11-1-12 最近的帖子
Thanks for the answers, guys.

Is it possible to turn on the Hibernate optimistic locking even though the Service Builder does not support it yet?
thumbnail
jelmer kuperus,修改在13 年前。

RE: Question about concurrent updates on the same entity

Liferay Legend 帖子: 1191 加入日期: 10-3-10 最近的帖子
No, what Minhchau suggests is probably as close as you can get. But like I mention, it's a flawed design
thumbnail
Minhchau Dang,修改在13 年前。

RE: Question about concurrent updates on the same entity

Liferay Master 帖子: 598 加入日期: 07-10-22 最近的帖子
Michal Cisty:
Is it possible to turn on the Hibernate optimistic locking even though the Service Builder does not support it yet?

If I'm understanding the Hibernate documentation correctly, it should be possible since it's all supposedly in the hibernate XML config file. However, since Liferay re-generates it each time, you'll need to reapply your customization every time you re-run service builder (which makes it very tedious).

For more clarity, you will need to specify the version column in your service.xml as a regular column (so Liferay knows to create it), edit the generated *-hbm.xml file according to the Hibernate documentation for version fields, and modify your service layer to catch the stale version exception and apply your logic appropriately, clearing out the Liferay entity cache if you don't rethrow the exception as a SystemException or PortalException.
Henrique Fernandes,修改在10 年前。

RE: Question about concurrent updates on the same entity

New Member 帖子: 6 加入日期: 10-6-2 最近的帖子
Hi,

Please read the following blog entry, there you can find a way to customize the generated hibernate files to enable optimistic locking:
http://zenidas.wordpress.com/recipes/optimistic-locking-in-liferay/

Regards,
Henrique