在我们的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_ID
是NVARCHAR(255)
,不可为空。
否则列上没有约束。 READ_COMMITTED
。答案 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语句 使用锁定提示由覆盖索引处理,获取锁定 覆盖索引中的索引键而不是数据行中的索引键 基表。