我有一个孤立的Azure SQL测试数据库,除了我的开发机器通过SSMS和开发Web应用程序实例之外没有活动连接。我是唯一一个使用这个数据库的人。
我正在一个包含大约1M记录的表上运行一些测试,我们需要在几乎所有~1M记录中对数据执行大型UPDATE
。
DECLARE @BatchSize INT = 1000
WHILE @BatchSize > 0
BEGIN
UPDATE TOP (@BatchSize)
[MyTable]
SET
[Data] = [Data] + ' a change'
WHERE
[Data] IS NOT NULL
SET @BatchSize = @@ROWCOUNT
RAISERROR('Updated %d records', 0, 1, @BatchSize) WITH NOWAIT
END
此查询工作正常,我可以看到我的数据每隔几秒一次更新1000条记录。
在INSERT
上执行额外的UPDATE
/ DELETE
/ MyTable
命令似乎受到运行批处理查询的影响,但这些操作在运行时会在几秒钟内执行。我假设这是因为在MyTable
上进行了锁定,而我的其他命令将在批量查询的锁定/循环迭代之间执行。
这种行为都是预料之中的。
但是,在批处理查询运行时,我经常注意到INSERT
上的其他UPDATE
/ DELETE
/ MyTable
命令将不再执行。他们总是超时/永不完成。我假设在MyTable
上发生了某种类型的锁定,但似乎锁定从未被释放。此外,即使我取消长时间运行的更新批处理查询,我仍然可以不再在INSERT
上运行任何UPDATE
/ DELETE
/ MyTable
命令。即使在数据库处于失效状态10-15分钟后,我也无法在MyTable
上执行写命令。我发现从发生的任何事情中“释放”数据库的唯一方法是将其向上和向下扩展到新的定价层。我假设这个定价层更改是回收/重新启动实例或其他东西。
在我今天的测试中,我多次重现了这种行为。
这里发生了什么?
向上/向下扩展层会回滚所有打开的事务并断开服务器登录。
关于你所看到的似乎是锁升级。尝试使用sp_getapplock序列化对数据库的访问。你也可以试试lock hints。