22,209
社区成员
发帖
与我相关
我的任务
分享
begin tran
UPDATE 表 SET f2=1 WHERE f2=0
waitfor delay '00:00:10' --延迟10秒测试用
commit tran
另一个窗口
SELECT * FROM 表 WHERE f2=0
后边这个窗口的语句是无法读取到上边更新语句的哪条数据的
[/quote]
你这个效率未必高啊,你看我的提问
你这个解决方法比如可能是10个人select成功了,但是在最后一步执行update的时候发现影响行数为0,那有9个人都要回滚[/quote]
不要让10个人都select成功,只让一个人select到数据,加一个UPDLOCK。
begin tran
SELECT * FROM 表 WITH (UPDLOCK) WHERE f2=0
.........
UPDATE 表 SET f2=1 WHERE f2=0
commit tran
[/quote]
SELECT * FROM 表 WITH (UPDLOCK) WHERE f2=0
这条语句基本就是锁表了吧?
我实现一次只需要取一条
SELECT top 1* FROM 表 WITH (UPDLOCK) WHERE f2=0
请问这种调用他是锁一条还是锁整个f2=0的
--在 tempdb 创建测试表及测试数据
USE tempdb
GO
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
GO
CREATE TABLE t(
f1 INT PRIMARY KEY,
f2 INT NOT NULL
)
GO
--插入 1000*1000 = 100 万 条数据
;WITH cte AS (
SELECT 1 AS c FROM [master].dbo.spt_values AS sv WHERE sv.[type]='P' AND sv.number BETWEEN 1 AND 1000
)
,cte2 AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid FROM cte AS a CROSS APPLY cte AS b
)
INSERT INTO t(f1,f2)
SELECT rid,rid%5+1 FROM cte2
--设置 20 条为 0 的数据作为更新测试用
UPDATE TOP (20) t SET f2=0 WHERE f1 % 5 = 0
--增加过滤索引
CREATE INDEX ix_t_f2 ON t(f2) WHERE f2=0
BEGIN TRAN
SELECT top 1 f1,f2 FROM t WITH(ROWLOCK,XLOCK,READPAST)
WHERE f2=0 order by f1
UPDATE t SET f2=1 WHERE f2=0
COMMIT TRAN
select top 10 * from t with(nolock)
begin tran
UPDATE 表 SET f2=1 WHERE f2=0
waitfor delay '00:00:10' --延迟10秒测试用
commit tran
SELECT * FROM 表 WHERE f2=0
begin tran
SELECT * FROM 表 WITH (UPDLOCK) WHERE f2=0
.........
UPDATE 表 SET f2=1 WHERE f2=0
commit tran
begin tran
UPDATE 表 SET f2=1 WHERE f2=0
waitfor delay '00:00:10' --延迟10秒测试用
commit tran
另一个窗口
SELECT * FROM 表 WHERE f2=0
后边这个窗口的语句是无法读取到上边更新语句的哪条数据的
[/quote]
你这个效率未必高啊,你看我的提问
你这个解决方法比如可能是10个人select成功了,但是在最后一步执行update的时候发现影响行数为0,那有9个人都要回滚begin tran
UPDATE 表 SET f2=1 WHERE f2=0
waitfor delay '00:00:10' --延迟10秒测试用
commit tran
SELECT * FROM 表 WHERE f2=0
begin tran
UPDATE 表 SET f2=1 WHERE .......
commit tran