Let\'s first forget about Hibernate. Assume that I have two tables, A & B. Two transactions are updating same records in these two tables, but txn 1 update B and then
Regarding first example - this kind of stuff is handled by database (read more about transaction isolation levels and locking strategies of your database). There are many different ways this can be handled.
As to Hibernate, javadoc to org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(EventSource) says:
Execute all SQL and second-level cache updates, in a special order so that foreign-key constraints cannot be violated:
I assume that this is the only optimization of executed SQL queries Hibernate makes. The rest of problems is handled by database.
The problem you describe is not handled by the database, and from my experience is not entirely handled by Hibernate either.
You have to take explicit steps to avoid it being a problem.
Hibernate does some of the work for you. As per the previous answer, Hibernate ensures that within an isolated flush the inserts, deletes and updates are ordered in a way that ensures that they will be applied in an achievable order. See performExecutions(EventSource session) in the AbstractFlushingEventListener class:
Execute all SQL (and second-level cache updates) in a special order so that foreign-key constraints cannot be violated:
- Inserts, in the order they were performed
- Updates
- Deletion of collection elements
- Insertion of collection elements
- Deletes, in the order they were performed
When having unique constraints it's very important to know this order, especially if you want to replace a one-to-many child (delete old/insert new) but both the old and the new child share the same unique constraints (e.g. same email address). In this case you could update the old entry, instead of deleting/inserting, or you could flush after delete only to then continue inserting. For a more detailed example you can check this article.
Note that it does not specify the order of updates. Examining the Hibernate code leads me to think the update order will depend on the order in which the entities were added to the persistence context, NOT the order they were updated. That might be predictable in your code, but reading the Hibernate code did not leave me feeling I would rely on that ordering.
There are three solutions I can think of: