【发布时间】:2010-12-01 19:23:25
【问题描述】:
我正在使用隔离级别为READ_COMMITTED 和READ_COMMITTED_SNAPSHOT=ON 的Microsoft SQL Server 2005 数据库。
现在我想使用:
SELECT * FROM <tablename> FOR UPDATE
...以便其他数据库连接在尝试访问同一行“FOR UPDATE”时阻塞。
我试过了:
SELECT * FROM <tablename> WITH (updlock) WHERE id=1
...但这会阻止所有其他连接,即使选择“1”以外的 id。
对于 Oracle、DB2、MySql,执行 SELECT FOR UPDATE 的正确提示是什么?
编辑 2009-10-03:
这些是创建表和索引的语句:
CREATE TABLE example ( Id BIGINT NOT NULL, TransactionId BIGINT,
Terminal BIGINT, Status SMALLINT );
ALTER TABLE example ADD CONSTRAINT index108 PRIMARY KEY ( Id )
CREATE INDEX I108_FkTerminal ON example ( Terminal )
CREATE INDEX I108_Key ON example ( TransactionId )
很多并行进程都这样做SELECT:
SELECT * FROM example o WITH (updlock) WHERE o.TransactionId = ?
编辑 2009-10-05:
为了更好地了解我在下表中记录了所有尝试过的解决方案:
机制 |在不同的行块上选择 |在同一行块上选择 ------------------------------------+-------------- ------+-------------- 行锁 |没有 |不 更新锁、行锁 |是的 |是的 xlock,rowlock |是的 |是的 可重复阅读 |没有 |不 DBCC TRACEON (1211,-1) |是的 |是的 行锁,xlock,holdlock |是的 |是的 上锁,挂锁| 高分辨率照片| CLIPARTO是的 |是的 上锁,阅读过去 |没有 |不 我在寻找 |没有 |是的【问题讨论】:
-
我不仅在寻找优化器提示。另一种可能的解决方案是更改隔离级别、全局数据库属性……一切(但使用不同的数据库)都是可能的。
-
你想做什么需要这样的锁定。通常最好用正确的查询而不是服务器的“功能”来解决
-
您能否提供您正在使用的查询和表的 DDL,包括任何键和索引。
-
你确定你的其他查询不是事务隔离读取未提交?
-
作为一种解决方法,您可以尝试先对此行进行简单更新(而不真正更改任何数据)。之后,您可以继续选择 in 中的行进行更新。
标签: sql sql-server sql-server-2005 tsql read-committed-snapshot