Within my application I have a process which takes some time (30s – 5mins) and during that time manipulates database via JPA.
My problem is that I want to set the state of the process to its db entity:
void runProcess(Process process) {
process.setState("Started.");
em.merge(process);
... db manipulations
process.setState("First phase finished.");
em.merge(process);
... db manipulations
process.setState("Process finished.");
em.merge(process);
}
The problem is that only first update takes place and the others stay ignored.
I don’t get any errors and Hibernate logs I can see process update three times:
Hibernate: update process set state=? where id=?
But only the first update will take place.
Thanks.
Changes made to entities are made in memory, and are only written to the database at flush time (typically, at the end of the transaction).
And even if a fluch is made before the end of the transaction, or if you flush after each process state update, other concurrent transactions have a good chance of not seeing the new state, because transactions are isolated from each other, and the default isolation level is, most of the time, READ_COMMITTED (which means other transactions only see the changes once they are committed).
If you want to make the process state definitely written to the database, you need to write this state in a separate transaction.