“SELECT ... FOR UPDATE”不适用于Hibernate和MySQL

时间:2010-02-15 11:09:45

标签: mysql hibernate locking pessimistic

我们有一个系统,我们必须在一个实体中使用悲观锁定。我们正在使用hibernate,所以我们使用LockMode.UPGRADE。但是,它没有锁定。

  • 表格是InnoDB
  • 我们检查过锁定在数据库(5.0.32)中是否正常工作,因此这个错误http://bugs.mysql.com/bug.php?id=18184似乎没问题。
  • 我们已检查数据源是否包含autoCommit = false参数。
  • 我们检查过SQL hibernate(版本3.2)生成的包含“FOR UPDATE”。

谢谢,

3 个答案:

答案 0 :(得分:1)

我遇到了非常相似的事情。我在Spring中使用了@Transactional注释,并且我发布了一个select更新并且没有获取更新锁(我有其他线程发出相同的更新选择并且已经验证它们没有阻塞一把锁)。当我显式获取Hibernate会话并发出beginTransaction并在代码块周围提交时,一切正常。

这并没有给我一个关于Spring容器管理事务的温暖和模糊的感觉。

答案 1 :(得分:1)

当我遇到类似的问题时,原因是我的Spring管理事务配置错误。仔细检查你的Spring tx配置。

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

您需要autocommit = false这一事实也可能表明您未在交易中运营。当您尝试访问一对多集合时,是否还会获得延迟初始化异常?

我发现最直接的方法是确定Spring tx方面是否真正有效,就是使用调试器。在发出FOR UPDATE SQL的方法中放置一个断点。 Upstack直到你点击@Transactional类/方法。您应该在调用堆栈的下一次调用中看到Spring方面代理。

答案 2 :(得分:0)

最近我遇到了这样的问题。我们在2个tx管理器上工作,因为我们有不同的数据库,问题是事务是使用配置到其他数据库的txmanager,因为在执行select之前,与查询数据库的连接没有被禁用自动提交模式更新。使用正确的txmanager解决了这个问题。希望将来能帮助别人。