Just wanted your expert opinions on declarative transaction management for Spring. Here is my setup:
save*, readonly = false, rollback for Throwable
Things work fine with above setup. However when I say get*, readonly = true
, I see errors in my log file saying Database connection cannot be marked as readonly
. This happens for all get* methods in service layer.
Now my questions are:
A. Do I have to set get*
as readonly? All my get*
methods are pure read DB operations. I do not wish to run them in any transaction context. How serious is the above error?
B. When I remove the get*
configuration, I do not see the errors. Morever, all my simple get*
operations are performed without transactions. Is this the way to go?
C. Why would anyone want to have transactional methods where readonly = true
? Is there any practical significance of this configuration?
Thank you! As always, your responses are much appreciated!
Spring @Transactional annotationThe readOnly attribute can further be used by Spring to optimize the underlying data access layer operations. Prior to Spring 5.1, when using Hibernate, the readOnly attribute of the @Transactional annotation was only setting the current Session flush mode to FlushType.
A read-only transaction or query is a transaction which does not modify any data.
If we don't provide any value for readOnly in @Transactional, then the default value will be false. Generally, we use @Transactional(readOnly = true) for search or retrieval operation to make sure we can only perform the read-only operation. We can override readOnly behavior using @Modifying annotation.
Transactions indeed put locks on the database — good database engines handle concurrent locks in a sensible way — and are useful with read-only use to ensure that no other transaction adds data that makes your view inconsistent.
This post tells that the behaviour or the readOnly
flag is persistence-mechanism-dependent.
C. Yes, when using hibernate, it gives performance benefits by setting the flush mode to FLUSH_NEVER
(as described in the linked post)
B. Yes, JDBC calls do not require a transaction (hibernate requires one), so removing the @Transactional
configuration trims all transaction management.
A. I'd assume spring is calling connection.setReadOnly(true)
but your JDBC driver doesn't support this
The bottom-line is : don't use readonly
transactions with plain JDBC.
And another thing - transactions are supposed to span multiple queries. Don't make your transactions too fine-grained. Make them a unit of work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With