Hi,

I am using the database retry approach I have seen recommended on the forums where I use a preinterceptor on a TransactionProxyFactoryBean that retries operations when a Spring Dao TransientDataAccessException (or subclass) occurs. I am also using the Spring OpenSessionInViewFilter which keeps a Hibernate Session open for the duration of all my Hibernate database operations.

The Spring and Hibernate documentation states that you should not reuse a Hibernate Session after transaction rollback. I am using the Spring HibernateTransactionManager and I noticed that on rollback it clears the Session state by calling clear() on the session. I have not had any problems reusing the same Session in my retry logic because of this.

I could set the singleSession property to false in the OpenSessionInViewFilter and this would create a new session when the retry logic kicks in. However, this is a global settting and there are many operations that might be affected by this change.

I would like some advice as to whether I should continue to reuse the Hibernate Session after rollback because the HibernateTransactionManager is cleaning things up for me or if I should change the OpenSessionInViewFilter setting and risk the side-effects. Is there something that will bite me later if I reuse the sessions that isn't obvious now?

Here is an example of the Spring config for my services with my interceptor for clarity:

<bean id="retryInterceptor" class="TransientExceptionRetryInterceptor">
<property name="numRetries" value="3" />
</bean>

<bean id="widgetDao" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target">
<bean class="WidgetDaoImpl">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="widgetService" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="target">
<bean class="WidgetServiceImpl">
<property name="widgetDao">
<ref bean="widgetDao" />
</property>
</bean>
</property>
</bean>

<bean id="widgetOps" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="preInterceptors">
<ref bean="retryInterceptor" />
</property>
<property name="target">
<bean class="WidgetOpsImpl">
<property name="widgetService">
<ref bean="widgetService" />
</property>
<property name="sessionService">
<ref bean="sessionService" />
</property>
</bean>
</property>
</bean>



Thanks,
Mark