Mixing JDBC and Hibernate Access (old:HibernateTransactionManager rollback won't work
I'm facing a serious problem when dealing with the HibernateTransactionManager rollback method.
(I have to reimplement a jdbc layer with hibernate, while the api of the layer has to remain the same. Therefore I have to substitute a method wich uses the jdbc connection rollback method under the hood with a method that now uses the HibernateTransactionManager rollback method.)
I use the transactionManager the following way:
Code:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
transactionManager.rollback(status);
I know that my transactionManager is configured properly and rollback works. This is because i implemented some tests with AbstractTransactionalDataSourceSpringContextTests. After every test everything is rolled back properly. Also calling
Code:
this.transactionManager.rollback(this.transactionStatus);
in a Testcase works fine.
But when doing it in another bean (with properly injected transactionManager) a rollback won't work. I've played with several PropagationBehaviors and combinations on where in the code I set them.
I also took the AbstractTransactionalDataSourceSpringContextTests source code and designed my class like this (especially the behavior of TransactionDefinition and TransactionStatus).
When debugging the code I discovered that "my variant" behaves very similiar to the one of the AbstractTransactionalDataSourceSpringContextTests class.
In the Method "private void processRollback(DefaultTransactionStatus status)" of AbstractPlatformTransactionManager my variant does either a "doRollback(status);" or a"doSetRollbackOnly(status);" while the AbstractTransactionalDataSourceSpringContextTests rollback always does "doRollback(status);". This propagates forword to a "jdbcContext.connection().rollback();" and so on...
So to me, everything looks fine, but the results aren't...:confused:
Can anybody help with some hints on this?
Thanks in advance
ps: I have to stick to this pattern, so declarative or programmatic transaction demarcation is out of the way.
pps: i also tried the simple
Code:
Connection conn = DataSourceUtils.getConnection(dataSource);
conn.rollback();
or the more sophisticated?
Code:
TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(dataSource);
proxy.getConnection().rollback();
approach... but they won't work. The only rollback that worked so far was with AbstractTransactionalDataSourceSpringContextTests (same datasource, same transactionManager).
ppps:
spring 2.0.6
hibernate 3.2.4.sp1
hsql database (i also tried db2, but same result)
IllegalTransactionStateException
now i tried to check what happens if two different threads (started from the same class) gain access to the database-layer via the way mentioned above (mixed Hibernate and Jdbc access). i get the already mentioned exception again:
Code:
org.springframework.transaction.IllegalTransactionStateException:
Pre-bound JDBC Connection found! HibernateTransactionManager does not support
running within DataSourceTransactionManager if told to manage the DataSource
itself. It is recommended to use a single HibernateTransactionManager for all
transactions on a single DataSource, no matter whether Hibernate or
JDBC access.
Neither am I using DataSourceTransactionManager nor do I directly access Jdbc (only via JdbcTemplate and DataSourceUtils.getConnection(dataSource)).
I'm wondering what this might be...