【问题标题】:SQL Server exclusive row lock (XLOCK ROWLOCK) using Spring Transactions using HibernateSQL Server 独占行锁 (XLOCK ROWLOCK) 使用 Spring Transactions 使用 Hibernate
【发布时间】:2011-12-10 23:17:10
【问题描述】:

我正在尝试对一行进行选择并更新值。当我这样做时,我需要独占访问该行。换句话说,在我更新行之前,没有其他进程(VM 内部或外部)应该能够读取该行。当前值不应该是“可选择的”。我尝试了以下事务注释。

@Transactional(isolation = Isolation.SERIALIZABLE, readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class, timeout=960)

这在 Spring 上下文中绝对有效,但是在事务中间放置一个 sleep 语句时,我仍然能够使用数据库工具选择当前行值。

有没有办法使用 Spring/Hibernate 获得 XLOCK/ROWLOCK(以适当者为准)?

版本:

  • 春季:3.0.5.RELEASE
  • 休眠:3.6.3.Final
  • JTDS:1.2.4

如果我不能使用 Spring/Hibernate,将非常感谢提供 JTDS 示例的链接。

谢谢。

【问题讨论】:

  • 您是否尝试过在数据库工具上发出带有“for update”后缀的选择,然后尝试从应用程序运行程序?在运行上述查询之前,您可能还需要检查工具中的隔离级别。
  • 我会试试的。可能我已经获得了我需要的那种锁,而没有做任何改变。
  • 我认为这应该明确告诉您发生了什么,请更新您是否看到它没有锁定。
  • 我不能执行“FOR UPDATE”,但是当我使用“with (paglock,XLOCK)”时,我似乎得到了我想要的锁定。如果你发布你的答案,我会给你赏金。

标签: java sql-server hibernate spring transactions


【解决方案1】:

对 Hibernate 使用显式锁定。有更多信息here

但是,我认为你必须再想一想——你真的需要悲观锁吗?在大多数情况下,乐观锁效果更好,而 hibernate 很好地支持版本控制。

【讨论】:

  • 此表用作序列。我相信我需要悲观锁定以确保在我使用该值并递增它之前没有其他进程使用它。
  • 您需要无间隙序列吗?
  • 我怀疑这是一个要求。为什么?
  • 你真倒霉... ;) 试着先打它gplivna.eu/papers/gapless_sequences.htm。您还应该在您的方法中放置一个创建“文档”事务,为该事务生成数字。否则,如果文档创建已回滚,它可能会出现间隙。
【解决方案2】:

SERIALIZABLE 隔离级别允许其他事务读取数据,但不允许修改。所以你需要明确地SELECT ... FOR UPDATE(在Hibernate中:Query#setLockMode(LockMode.UPGRADE))。

【讨论】:

  • 能否在 SQL Server 中执行“FOR UPDATE”
  • 当然。 Somebody 已经这样做了。
猜你喜欢
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
相关资源
最近更新 更多