Announcement Announcement Module
Collapse
No announcement yet.
Pessimistic locking: same transaction blocks itself on following update Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pessimistic locking: same transaction blocks itself on following update

    I'm working on a Jetty/Hibernate/Spring/Atomikos/Oracle web service. Our implementation worked perfectly so far, but we now have to add some protection for concurrent transactions, and I can't make pessimistic locking work. The transaction that locks the database row with SELECT ... FOR UPDATE blocks on the following UPDATE.

    I can't add columns to the database, so I can't use optimistic locking.

    The high-level scenario is the following:

    1. Receive a request to update some record
    2. Retrieve the record using:
    Code:
    hibernateTemplate.find(queryString, values);
    3. Lock the record using:
    Code:
    hibernateTemplate.lock(entity, LockMode.UPGRADE);
    This calls SELECT ... FOR UPDATE underneath:
    Code:
    org.hibernate.SQL  - select F_SUBSCRIBER_PK from T_SUBSCRIBER where F_SUBSCRIBER_PK =? for update
    4. Attempt to update the record using:
    Code:
    hibernateTemplate.saveOrUpdate(entity);
    5. The thread blocks on the UPDATE forever:
    Code:
    org.hibernate.SQL  - update T_SUBSCRIBER set [...] where F_SUBSCRIBER_PK=?
    6. Atomikos times out after 30 seconds.

    The atomikos debug logs show a single transaction ID. Between the select for update and the update, hibernate does some collection loading, probably in preparation for the update. That implies a select from some related tables that seems to execute correctly.

    I wonder if I'm missing something in the config somewhere.

    The config looks like this:
    Code:
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/Central" />
    	<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.Oracle9iDialect</prop>
    				<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory
    				</prop>
    				<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
    				</prop>
    				<prop key="hibernate.connection.isolation">1</prop>
    				<prop key="hibernate.current_session_context_class">jta</prop>
    				<prop key="jta.UserTransaction">UserTransaction</prop>
    				<prop key="hibernate.cache.use_second_level_cache">false</prop>
            		<prop key="hibernate.cache.use_query_cache">false</prop>
    			</props>
    		</property>
    		<property name="annotatedClasses">...</property>
    	</bean>
    	...
    </jee>
    And this:
    Code:
    <New id="msdpCentral" class="org.mortbay.jetty.plus.naming.Resource">
    	<Arg>jdbc/Central</Arg>
    	<Arg>
    		<New class="org.apache.commons.dbcp.BasicDataSource">
    			<Set name="driverClassName">oracle.jdbc.driver.OracleDriver</Set>
    			...
    			<Set name="initialSize">20</Set>
    			<Set name="maxActive">200</Set>
    			<Set name="maxWait">10000</Set>
    			<Set name="validationQuery">SELECT 1 FROM DUAL</Set>
    		</New>
    	</Arg>
    </New>
    Atomikos config:
    Code:
    com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
    com.atomikos.icatch.serial_jta_transactions=false
    com.atomikos.icatch.max_actives=15000
    com.atomikos.icatch.default_jta_timeout=30000
    com.atomikos.icatch.max_timeout=60000
    com.atomikos.icatch.output_dir=target/atomikos/
    com.atomikos.icatch.log_base_dir=target/atomikos/logs
    Last edited by jmtremblay; Dec 1st, 2009, 12:59 PM. Reason: More formatting.

  • #2
    By the way, if anybody cares, we never found the cause of this issue and just stopped using Atomikos in favor of Spring's transaction manager.

    Comment


    • #3
      Yes we care

      Hi,

      Personally I care, and I would have seen this earlier if it had been posted in the Atomikos forums instead :-)

      Anyway, setting serial_jta_transactions to true might have helped...

      But if you only have one database (no queues or anything) then Spring's native transactions sound fine, I see no need for JTA there.

      Best
      Guy

      Comment

      Working...
      X