Reputation: 1578
Is it possible to heal exceptions that arise during saving/committing a hibernate session?
Background: We are currently updating several hundred records per session, using FluentNHibernate. Each now and then, there is a StaleException thrown because one of the records were changed by other processes. I see that the exception is giving me the Id of the record that caused trouble, so theoretically, i could try to evict/reload the object and try the modification of the object again instead of rolling back the entire hibernate transaction.
Would that work trying to call Commit a second time, or has the session become invalid because of the exception thrown?
Upvotes: 0
Views: 127
Reputation: 10812
After you have an exception, you're out of luck. You need to restart with new Session.
Optimistic locking is good if version failures are rare. If not, you should make them rare. You probably have more users editing the same record: you can, for example, mark the record as being edited, by setting a timestamp on the moment one user opens it for editing. The timestamp will be set to now+X minutes
. If second user comes and the timestamp is not in the past, you'll show him a warning that someone else is editing.
Second approach could be that you load and compare current versions of to-be-modified entities. If there is a conflict, you'll show an UI to resolve the conflict. If the user decides to overwrite other's changes, you can update objectVersion
on his entity to the current value and the update will proceed.
You can also exclude some properties from version checking, so that if only these properties are changed, version won't be incremented. For example, we have it disabled for the User.lastActivity
field, as it is updated at each activity of the user and could cause unnecessary errors.
Upvotes: 1
Reputation: 1578
It seems what i was trying to do is impossible; you have to use a new session if any exception occurs while flushing to database...
https://ayende.com/blog/3946/nhibernate-mapping-concurrency
Excerpt: "If the update fails because the row was updated, we will get a StaleObjectException. Like all exceptions, this will make the session ineligible for use, and you would have to create a new session to handle it."
I´ll have to redesign my process to handle every single record with a designated session.
Upvotes: 0