SELECT FOR UPDATE与SQL Server

我正在使用隔离级别为READ_COMMITTEDREAD_COMMITTED_SNAPSHOT=ON的Microsoft SQL Server 2005数据库。

现在我想用:

SELECT * FROM <tablename> FOR UPDATE

...以便在尝试访问同一行“FOR UPDATE”时阻塞其他数据库连接。

我试过了:

SELECT * FROM <tablename> WITH (updlock) WHERE id=1

...但是,即使选择了“1”以外的其他连接,也会阻止其他连接。

正如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:

为了更好地概述,我已经在下表中写下了所有尝试过的解决方案:

mechanism              | SELECT on different row blocks | SELECT on same row blocks
-----------------------+--------------------------------+--------------------------
ROWLOCK                | no                             | no
updlock, rowlock       | yes                            | yes
xlock,rowlock          | yes                            | yes
repeatableread         | no                             | no
DBCC TRACEON (1211,-1) | yes                            | yes
rowlock,xlock,holdlock | yes                            | yes
updlock,holdlock       | yes                            | yes
UPDLOCK,READPAST       | no                             | no

I'm looking for        | no                             | yes

最近我有一个死锁问题,因为Sql Server锁定更多然后必要(页面)。 你不能对此做任何事情。 现在我们捕捉到了死锁例外......我希望我有Oracle。

编辑:我们同时使用快照隔离,它可以解决很多问题,但不是所有问题。 不幸的是,为了能够使用快照隔离,它必须被数据库服务器所允许,这可能在客户站点造成不必要的问题。 现在我们不仅捕获死锁异常(当然还会发生),还包括快照并发问题,以便从后台进程重复事务(用户不能重复)。 但是这仍然比以前表现得更好。


我有一个类似的问题,我想只锁定1行。 据我所知,使用UPDLOCK选项,SQLSERVER会锁定所有需要读取的行以获取行。 因此,如果您未定义索引来直接访问该行,则所有先前的行都将被锁定。 在你的例子中:

假设你有一个名为TBL的表和id字段。 你想锁定id=10的行。 您需要为字段ID(或您选择的任何其他字段)定义索引:

CREATE INDEX TBLINDEX ON TBL ( id )

然后,您的查询仅锁定您读取的行:

SELECT * FROM TBL WITH (UPDLOCK, INDEX(TBLINDEX)) WHERE id=10.

如果不使用INDEX(TBLINDEX)选项,则SQLSERVER需要从表的开头读取所有行以查找id=10行,以便这些行将被锁定。


您无法同时进行快照隔离和阻止读取。 快照隔离的目的是防止阻塞读取。

链接地址: http://www.djcxy.com/p/5613.html

上一篇: SELECT FOR UPDATE with SQL Server

下一篇: Confused about UPDLOCK, HOLDLOCK