验证思路:
假设游标是全部查询出来放到内存中。第一个线程假如查询数据有(ID为:1,2,3,4,5,6)6条数据放到内存中,第二个线程查询数据有(ID为:1,2,3,4,5,6)6条数据放到内存中。第一个线程开始遍历修改。由于要修改的数据都在内存中,所以肯定会全部修改的。同理,第二个线程也会全部修改的。
准备SQL:
CREATE TABLE [dbo].[Test](
[Id] [int] IDENTITY(1,1) NOT NULL,
[status] [int] NULL,
CONSTRAINT [PK__Table__3214EC07B53FDC36] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Test] ON
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (1, 0)
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (2, 0)
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (3, 0)
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (4, 0)
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (5, 0)
GO
INSERT [dbo].[Test] ([Id], [status]) VALUES (6, 0)
GO
SET IDENTITY_INSERT [dbo].[Test] OFF
GO
验证SQL:
DECLARE @id INT,@status int; DECLARE cursor_message CURSOR FOR SELECT id,status from [dbo].[Test] where status =0 OPEN cursor_message FETCH NEXT FROM cursor_message INTO @id,@status WHILE @@FETCH_STATUS = 0 begin PRINT @id update [Test] set status = 1 WHERE ID = @id waitfor delay '00:00:1'; FETCH NEXT FROM cursor_message INTO @id,@status END CLOSE cursor_message; --释放游标 deallocate cursor_message
开两个查询窗口分别执行
窗口一:
窗口二
结论
如果一次查询放到内存中会全部修改,所以说游标的查询方式遍历一条查询一条