I am in the process of optimizing an algorithm, and I noticed that Hibernate creates and releases update statements repetitively instead of reusing them. These are all from the same query.
15:57:31,589 TRACE [.JdbcCoordinatorImpl]:371 - Registering statement [sql : 'update ...
15:57:31,591 TRACE [.JdbcCoordinatorImpl]:412 - Releasing statement [sql : 'update ...
15:57:31,592 TRACE [.JdbcCoordinatorImpl]:525 - Closing prepared statement [sql : 'update ...
15:57:31,592 TRACE [.JdbcCoordinatorImpl]:278 - Starting after statement execution processing [ON_CLOSE]
15:57:31,594 TRACE [.JdbcCoordinatorImpl]:371 - Registering statement [sql : 'update ...
15:57:31,595 TRACE [.JdbcCoordinatorImpl]:412 - Releasing statement [sql : 'update ...
15:57:31,596 TRACE [.JdbcCoordinatorImpl]:525 - Closing prepared statement [sql : 'update ...
15:57:31,596 TRACE [.JdbcCoordinatorImpl]:278 - Starting after statement execution processing [ON_CLOSE]
15:57:31,597 TRACE [.JdbcCoordinatorImpl]:371 - Registering statement [sql : 'update ...
15:57:31,599 TRACE [.JdbcCoordinatorImpl]:412 - Releasing statement [sql : 'update ...
15:57:31,600 TRACE [.JdbcCoordinatorImpl]:525 - Closing prepared statement [sql : 'update ...
15:57:31,601 TRACE [.JdbcCoordinatorImpl]:278 - Starting after statement execution processing [ON_CLOSE]
The algorithm's main method has a @Scope
and a @Transactional
annotation. The expected behavior is that, if anything goes wrong, the algorithm's updates are ROLLBACK
.
Beneath, the algorithm uses a @Service
which has a different @Scope
and is also @Transactional
. The service is the one using Hibernate to update the database, with session.update(entity)
. The documentation says that, by default, nested transactions reuse the transaction if it exists.
Thanks for your attention
The @Transactional annotation is metadata that specifies that an interface, class, or method must have transactional semantics; for example, "start a brand new read-only transaction when this method is invoked, suspending any existing transaction".
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.
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
Your understanding is correct. The scope is not related to how transactions are propagated, Spring should wrap your beans with proxies that control transactions regardless of scope.
There is no way to reuse statements when using Hibernate. Even when writing JDBC code manually it is not recommended approach, due to entanglement of code that such approach forces. Common answer to this is to use prepared statement cache on JDBC connection pool. For example with Apache DBCP pool you can use poolPreparedStatements
and maxOpenPreparedStatements
to control that. Pools bundled with application servers have similar settings.
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