Reputation: 18848
Most of us might be using Spring and Hibernate for data access. I am trying to understand few of the internals of Spring Transaction Manager.
According to Spring API, it supports different Isolation Level - doc But I couldn't find clear cut information on which occasions these are really helpful to gain performance improvements.
I am aware that readOnly
parameter from Spring Transaction
can help us to use different TxManagers to read-only data and can leverage good performance. But it locks
the table to get the data to avoid dirty-reads/non-committed reads - doc.
Assume, in few occasions, we might want to blindly insert the records into a table and retrieve the information without locking the table, a case where we never update the table data, we just insert and read [append-only]. Can we use better Isolation to gain any performance?
Upvotes: 4
Views: 6079
Reputation: 153690
Read-only
allows certain optimizations like disabling dirty checking and you should totally use it when you don't plan on changing an entity.
Each isolation level defines how much locking a database has to impose for ensuring the data anomaly prevention.
Most database use MVCC (Oracle, PostgreSQL, MySQL) so readers don't lock writers and writers don't lock readers. Only writers lock writers as you can see in the following example.
REPEATABLE_READ
doesn't have to hold a lock to prevent a concurrent transaction from modifying your current transaction loaded rows. The MVCC engine allows other transactions to read the committed state of a row, even if your current transaction has changed it but hasn't yet committed (MVCC uses the undo logs to recover the previous version of a pending changed
row).
In your use case you should use READ_COMMITTED
as it scales better than other more strict isolation levels and you should use optimistic locking for preventing lost updates in long conversations.
Setting @Transactional(isolation = Isolation.SERIALIZABLE)
to a Spring bean has a different behaviour, depending on the current transaction type:
RESOURCE_LOCAL
transactions, the JpaTransactionManager
can apply the specific isolation level for the current running transaction.WebLogicJtaTransactionManager
.Upvotes: 4
Reputation: 9309
Actually readOnly=true
doesn’t cause any lock contention to the database table, because simply no locking is required - the database is able to revert back to previous versions of the records ignoring all new changes.
With readOnly as true, you will have the flush mode as FlushMode.NEVER
in the current Hibernate Session preventing the session from committing the transaction. In addition, setReadOnly(true)
will be called on the JDBC Connection, which is also a hint to the underlying database not to commit changes.
So readOnly=true
is exactly what you are looking for (e.g. SERIALIZED
isolation level).
Here is a good explanation.
Upvotes: 2