views:

717

answers:

2

Hi,

We have a system in which we must use pessimistic locking in one entity. We are using hibernate, so we use LockMode.UPGRADE. However, it does not lock.

  • The tables are InnoDB
  • We have checked that locking works correctly in the database (5.0.32), so this bug http://bugs.mysql.com/bug.php?id=18184 seems to be no problem.
  • We have checked that datasource includes the autoCommit = false parameter.
  • We have checked that the SQL hibernate (version 3.2) generates includes the " FOR UPDATE".

Thanks,

+1  A: 

I'm running into something very similar. I'm using the @Transactional annotation in Spring and I'm issuing a select for update and the update lock is not being acquired (I have other threads that are issuing the same select for update and have verified that they're not blocking on a lock). When I explicitly get the Hibernate session and issue a beginTransaction and commit around the code block, it all works.

This does not give me a warm and fuzzy feeling about Spring container managed transactions.

DaveR
+1  A: 

When I've had similar problems, it was because I had the Spring managed transactions misconfigured. Double check your Spring tx config.

<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>

The fact that you need autocommit = false may also indicate that you're not operating within a transaction. Do you also get lazy initialization exceptions when you try to access one-to-many collections?

The most direct way I've found to figure out if the Spring tx aspect is actually working is to use the debugger. Put a breakpoint in the method that issues the FOR UPDATE SQL. Upstack until you hit your @Transactional class/method. You should see the Spring aspect proxy in the next call up in the call stack.

dave