I'm using Spring with Hibernate with an application-ctx of:
The GenericDaoHibernateImpl implements a GenericDao interface that looks like this:Code:<?xml version="1.0" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> <property name="url" value="jdbc:hsqldb:mem:testdb" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop> </props> </property> <property name="annotatedClasses"> <list> <value>com.pd.springHibernate.domain.Person</value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven/> <bean id="personDao" class="com.pd.springHibernate.dao.GenericDaoHibernateImpl"> <constructor-arg> <value>com.pd.springHibernate.domain.Person</value> </constructor-arg> <property name="sessionFactory" ref="sessionFactory"/> </bean> </beans>
The longRunningUpdate method sleeps for a couple seconds on either side of a SessionFactory.getCurrentSession().update( Object ). So with it, I can test the transactional nature of the DAO.Code:@Transactional public interface GenericDao< T, PK extends Serializable > { PK create( T newInstance ); T read( PK id ); void update( T transientObject ); void delete( T persistentObject ); void longRunningUpdate( T transientObject ); }
What I'd expect:
1) I have a thread call longRunningUpdate.
2) While step one is running (it takes several seconds to complete), I have another thread call update - a different method that does exactly the same thing as longRunningUpdate but has no sleep delays.
3) I'd expect the 2nd thread should either block until the 1st thread finishes or possibly throw an exception since it can't immediately complete.
BUT WHAT ACTUALLY HAPPENS: the 2nd thread happily updates/persists the object - even though longRunningUpdate should be blocking it since it started before the 2nd thread and still hasn't finished yet.
Now, if instead of calling update the 2nd thread calls longRunningUpdate just like the 1st thread does, then it does wait until the 1st thread finishes before doing its work.
So it seems the locking I have is only when two threads call the same method - not the same DAO.
Is there a way (using Hibernate and no J2EE infrastructure) to get such coarser grained transactional behavior?
Thanks!
Sean


Reply With Quote
).