为了适应给定表的并发性,该表将不断受到更新和选择的攻击,我试图在Azure SQL DB上引入一种高效的锁定模式。在调查了READPAST的选择和WITH(ROWLOCK(的更新后,我没有看到我预期的结果,其他人也没有报告。我的带有READPAST的select语句总是返回正在更新的行。考虑一下我的简单场景:
表[作业]:Id varchar(12(PK |创建日期时间|状态Id smallint
我为Job表设置了5条记录的种子,并将所有记录的StatusId设置为0。
在一个会话中,我执行以下命令而不提交:
BEGIN TRANSACTION
UPDATE JOB WITH (ROWLOCK) SET StatusId = 1
在另一个会话中,我执行以下命令
SELECT * FROM Job WITH (READPAST)
select语句执行并返回所有5行及其预更新的StatusId(0(。我的理解是READPAST应该跳过被锁定的行。我已经使用sp_WhoIsActive proc验证了锁是否确实存在并授予了锁。
要使此场景正常工作,我缺少什么?
谢谢你的帮助。
Azure SQL数据库默认启用READ_COMMITTED_SNAPSHOT
数据库选项。这在READ_COMMITTED
隔离级别中使用行版本控制而不是锁定以实现读取一致性,因此SELECT
查询将返回更新前的行版本,直到提交UPDATE
事务为止。
您可以使用如下提示覆盖SELECT查询中的隔离级别:
SELECT * FROM dbo.job WITH(REPEATABLEREAD, READPAST);