简体   繁体   中英

A good strategy/solution for concurrency with hibernate's optimistic/pessimistic locking

Let's presume that we have an application "mail client" and a front-end for it.

If a user is typing a message or editing the subject or whatever, a rest call is made to update whatever the user was changing (eg the receivers) to keep the message in DRAFT. So a lot PUT's are happening to save the message. When closing the window, an update of every editable field happens at the same time. Hibernate can't handle this concurrency: Each of those calls retrieve the message, edit their own fields and try to save the message again, while the other call already changed it.

I know I can add a rest call to save all fields at the same time, but I was wondering if there is a cleaner solution, or a decent strategy to handle such cases (like for example only updating one field or some merge strategy if the object has already changed)

Thanks in advance!

The easiest solutions here would be to tweak the UI to either

  • Submit a single rest call during email submission that does all the tasks necessary.
  • Serialize the rest calls so they're chained rather than firing concurrently.

The concern I have here is that this will snowball at some point and become a bigger concurrency problem as more users are interacting with the application. Consider for the moment the potential number of concurrent rest calls your web infrastructure will have to support alone when you're faced with a 100, 500, 1000, or even 10000 or more concurrent users.

Does it really make sense to beef up the volume of servers to handle that load when the load itself is a product of a design flaw in the first place?

Hibernate is designed to handle locking through two mechanisms, optimistic and pessimistic.

Optimistic Way

  1. Read the entity from the data store.
  2. Cache a copy of the fields you're going to modify in temporary variables.
  3. Modify the field or fields based on your PUT operation.
  4. Attempt to merge the changes.
  5. If save succeeds, you're done.
  6. Should an OptimisticLockException occur, refresh the entity state from data store.
  7. Compare cached values to the fields you must change.
  8. If values differ, you can assert or throw an exception
  9. If they don't differ, go back to 4.

The beautiful part of the optimistic approach is you avoid any form of deadlock happening, particularly if you're allowing multiple tables to be read and locked separately.

While you can use pessimistic lock options, optimistic locking is generally the best accepted way to handle concurrent operations as it has the least concurrency contention and performance impact.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM