(UPDLOCK,ROWLOCK)锁定整个表甚至很难选择只有1行

时间:2017-05-03 14:49:46

标签: java sql sql-server locking

在我们的Java应用程序中,我们使用 SQL Server 语句暂停某些进程。

这是SQL语句:

SELECT * FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0');

IN子句中的UUID当然会在运行之间发生变化。

这是我们用于锁定的Java代码:

entityManager.createNativeQuery(sqlString).getResultList()

上面的SQL语句只返回一行。不幸的是,似乎整个表都被锁定了。结果是所有进程都被锁定,即使没有或只有一些进程被阻止。

为什么即使我指定UPDLOCK

,整个表也会被锁定

其他信息:

  • MESSAGES.INTERNAL_IDNVARCHAR(255),不可为空。 否则列上没有约束。
  • 隔离级别为READ_COMMITTED

1 个答案:

答案 0 :(得分:1)

这是因为您的MESSAGES.INTERNAL_ID不是关键。一旦行被锁定,您无法读取它并检查它的值。尝试在此列上创建主键。

如果不可能,请在其上创建INDEX并重写您的查询:

SELECT MESSAGES.INTERNAL_ID FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0');

MSDN说:

  

Lock提示获取行级锁的ROWLOCK,UPDLOCK和XLOCK   可能将锁定放在索引键而不是实际数据行上。对于   如果表具有非聚簇索引和SELECT语句   使用锁定提示由覆盖索引处理,获取锁定   覆盖索引中的索引键而不是数据行中的索引键   基表。