Zohaib
Zohaib

Reputation: 7116

hibernate get data after flush before commit

In my service class (which is annotated as Transactional), I update and then save the object as:

myObj.save(flush:true)   //(Thread A, updates the value, Step A)

After this, processing of data takes place which takes a long time. During this processing a lot of changes are made in the domain classes but those changes are not relevant here. Since all of this processing is happening in the same service class, it is part of a single transaction.

Now, in the meantime, when all of this processing is going on, another thread, which is part of a different hibernate session, access

MyObj.findAll() //Thread B and in the result set I see the updated value. Value which was updated in Step A However, thread A is not finished yet and thus changes are not committed to database yet. I can confirm this because at the same time if I run query directly in mysql workbench then I do not see the changes. Changes only visible when objects accessed via hibernate.

I was under impression that if changes are made as a result of flush, then those changes are visible in the same transaction and not in other transactions. Can someone please clarify?

Upvotes: 0

Views: 1239

Answers (1)

Shadow
Shadow

Reputation: 34285

The answer is that this depends on the isolation level used in the mysql server. As mysql documentation on innodb transaction isolation levels says:

the isolation level is the setting that fine-tunes the balance between performance and reliability, consistency, and reproducibility of results when multiple transactions are making changes and performing queries at the same time.

InnoDB offers all four transaction isolation levels described by the SQL:1992 standard: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. The default isolation level for InnoDB is REPEATABLE READ.

The documentation describes the differences between the various levels at a great detail. I would like to draw your attention particularly to the read uncommited level:

SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used. Thus, using this isolation level, such reads are not consistent. This is also called a dirty read. Otherwise, this isolation level works like READ COMMITTED.

This isolation level enables a query to read data updated by other transactions, which have not been commited yet. Before using this isolation level in your code, however, pls ensure that you understand all implications of this isolation level. You cannot cherry-pick which transactions' uncommited data you want to see. So, you may opt to wait just a little bit longer to get the commited data.

Upvotes: 1

Related Questions