Spring 1.2 + Hibernate aggressive release + read-only txn
After upgrading to Spring 1.2 final (from RC2), I was shocked to see that my app blows up at runtime, in semi-random fashion. The JDBC driver is telling me that I was trying to do updates while the transaction is read-only.
The config is as follows:
- Spring 1.2
- C3P0 0.8.5.2
- Hibernate 3.0.3
- PostgreSQL 8.0.3 + JDBC3 311 build driver
- load* and find* are PROPAGATION_REQUIRED,readOnly
- others are PROPAGATION_REQUIRED
My 1st question is: Is aggressive release and read-only txn a wrong combination?
Long story short (a few hours of debugging and tracing), I found Spring would reset the connection's readOnly status by doing cleanupAfterCompletion() near the end of commit of AbstractPlatformTransactionManager.
If aggressive release is enabled, Hibernate will call ConnectionProvider directly to close the connection, the connection (possibly still "read-only") is returned to the pool as a result. When Spring finally get the chance to do the normal cleanup, it gets a connection from the pool again. If it is luckly, that particular connection will be picked, and bad things won't happen. Otherwise, when some other transaction picks up that connection and do some updates, a nasty SQLException will be thrown.
Workaround: set hibernate.connection.release_mode to on_close (for the bean definition of the LocalSessionFactoryBean) to restore the old behaviour.
My 2nd question is: Is this the way to go? If yes, some additional documentation would help. If there is any other way, I would like to know too.