Help! Transactions not working -- newbie question
I'm new to the spring framework, and am liking it so far. However, I cannot get transactions to work for the life of me.... I am trying to use programmatic transactions at the moment, I'll play with the declarative ones later. Here is the code I am using:
Code:
private void sendHeartbeat() {
PlatformTransactionManager transactionManager = Spring.getTransactionManager();
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
DataSource ds = Spring.getDataSource();
JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
jdbcTemplate.update(HEARTBEAT_SQL, new Object[]{NODE_NAME});
status.setRollbackOnly();
transactionManager.rollback(status);
log.info("Rolled back!");
}
This has been modified several times based on forum messages I've read and what I've gathered from the docs, so it's probably a lot more verbose than it needs to be.
The basi c problem is that even though I am forcing a rollback (remeber, this code is just for testing and learning the framework) the rollback never happens. I always see the results committed to the database.
My relevent configuration is:
Code:
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingResources">
<value>/test.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
What am I doing wrong?
-- EDIT --
Turned on full debugging, got this as output:
Code:
[java] 10:48:13,516 INFO [SQLErrorCodesFactory] Looking up default SQLErrorCodes for DataSource
[java] 10:48:13,516 INFO [SQLErrorCodesFactory] Database product name found in cache for DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@1911540]. Name is 'Oracle'.
[java] 10:48:13,522 DEBUG [JdbcTemplate] Executing SQL query [select node_name from node_info where active = 'T' and rownum = 1 order by node_info_id ]
[java] 10:48:13,523 DEBUG [DriverManagerDataSource] Creating new JDBC connection to [jdbc:oracle:thin:@192.168.0.233:1521:meddev]
[java] 10:48:13,715 INFO [ClusterNode] Assuming role of master node
[java] 10:48:18,723 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'transactionManager'
[java] 10:48:18,725 DEBUG [HibernateTransactionManager] Using transaction object [org.springframework.orm.hibernate.HibernateTransactionObject@1be2893]
[java] 10:48:18,726 DEBUG [HibernateTransactionManager] Creating new transaction
[java] 10:48:18,726 DEBUG [SessionFactoryUtils] Opening Hibernate session
[java] 10:48:18,726 DEBUG [HibernateTransactionManager] Opened new session [net.sf.hibernate.impl.SessionImpl@159e154] for Hibernate transaction
[java] 10:48:18,726 DEBUG [HibernateTransactionManager] Exposing Hibernate transaction as JDBC transaction [C3P0ProxyConnection [Invocation Handler: com.mchange.v2.c3p0.impl.C3P0PooledConnection$ProxyConnectionInvocationHandler@1d87b85]]
[java] 10:48:18,727 DEBUG [TransactionSynchronizationManager] Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1958bf9] for key [com.mchange.v2.c3p0.ComboPooledDataSource@a522a6] to thread [Thread-5]
[java] 10:48:18,727 DEBUG [TransactionSynchronizationManager] Bound value [org.springframework.orm.hibernate.SessionHolder@118958e] for key [net.sf.hibernate.impl.SessionFactoryImpl@19fe451] to thread [Thread-5]
[java] 10:48:18,727 DEBUG [TransactionSynchronizationManager] Initializing transaction synchronization
[java] 10:48:18,727 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'dataSource'
[java] 10:48:18,727 INFO [SQLErrorCodesFactory] Looking up default SQLErrorCodes for DataSource
[java] 10:48:18,727 INFO [SQLErrorCodesFactory] Database product name found in cache for DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@1911540]. Name is 'Oracle'.
[java] 10:48:18,728 DEBUG [JdbcTemplate] Executing SQL update [update node_info set last_heartbeat = sysdate where node_info_id in ( select max(node_info_id) from node_info where active='T' and node_name = ? ) and rownum = 1 ]
[java] 10:48:18,728 DEBUG [DriverManagerDataSource] Creating new JDBC connection to [jdbc:oracle:thin:@192.168.0.233:1521:meddev]
[java] 10:48:18,881 DEBUG [DataSourceUtils] Registering transaction synchronization for JDBC connection
[java] 10:48:18,882 DEBUG [TransactionSynchronizationManager] Bound value [org.springframework.jdbc.datasource.ConnectionHolder@102b2b6] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1911540] to thread [Thread-5]
[java] 10:48:18,882 DEBUG [TransactionSynchronizationManager] Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@102b2b6] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1911540] bound to thread [Thread-5]
[java] 10:48:18,882 DEBUG [StatementCreatorUtils] Setting SQL statement parameter value; columnIndex=1, parameter value='Test Node', valueClass=java.lang.String, sqlType=unknown
[java] 10:48:18,885 DEBUG [JdbcTemplate] SQL update affected 1 rows
[java] 10:48:18,887 INFO [ClusterNode] Rolled back!
[java] 10:48:18,888 DEBUG [HibernateTransactionManager] Transactional code has requested rollback
[java] 10:48:18,888 DEBUG [HibernateTransactionManager] Triggering beforeCompletion synchronization
[java] 10:48:18,888 DEBUG [TransactionSynchronizationManager] Removed value [org.springframework.jdbc.datasource.ConnectionHolder@102b2b6] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1911540] from thread [Thread-5]
[java] 10:48:18,921 DEBUG [HibernateTransactionManager] Initiating transaction rollback
[java] 10:48:18,921 DEBUG [HibernateTransactionManager] Rolling back Hibernate transaction on session [net.sf.hibernate.impl.SessionImpl@159e154]
[java] 10:48:18,921 DEBUG [HibernateTransactionManager] Triggering afterCompletion synchronization
[java] 10:48:18,922 DEBUG [TransactionSynchronizationManager] Clearing transaction synchronization
[java] 10:48:18,922 DEBUG [TransactionSynchronizationManager] Removed value [org.springframework.orm.hibernate.SessionHolder@118958e] for key [net.sf.hibernate.impl.SessionFactoryImpl@19fe451] from thread [Thread-5]
[java] 10:48:18,922 DEBUG [TransactionSynchronizationManager] Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1958bf9] for key [com.mchange.v2.c3p0.ComboPooledDataSource@a522a6] from thread [Thread-5]
[java] 10:48:18,922 DEBUG [HibernateTransactionManager] Closing Hibernate session [net.sf.hibernate.impl.SessionImpl@159e154] after transaction
[java] 10:48:18,922 DEBUG [SessionFactoryUtils] Closing Hibernate session
[java] 10:48:18,923 DEBUG [DefaultListableBeanFactory] Returning cached instance of singleton bean 'dataSource'
It appears that the transaction is trying to get rolled back, but I don't see it happening....???