我有两个测试事务,分别在两个会话中。假设这两个事务将同时运行。我尝试的是让一个事务在另一个事务完成后正确插入发票号码。不重复。我按如下方式执行。但如果我在第二个会话中删除(tablockx),它们将无法工作。我在网上查看了书籍,但没有答案。请问是否有人可以帮忙?Serializable不起作用,因为这里两个SELECT想要彼此独占。谢谢。
在第一会话中:
在第一会话中:
begin transaction
declare @i int
select @i=MAX(InvNumber) from Invoice
with(tablockx)
where LocName='A'
waitfor delay '00:00:10'
set @i=@i+1
insert into Invoice values('A',@i);
commit
在第二节课中:
begin transaction
declare @i int
select @i=MAX(InvNumber) from Invoice
with(tablockx)
where LocName='A'
set @i=@i+1
insert into Invoice values('A',@i);
commit
HOLDLOCK
始终锁定查询指定的整个范围,两个并发事务无法在同一资源上具有UPDLOCK
。 - Martin SmithBEGIN TRANSACTION DECLARE @i INT SELECT @i = MAX(InvNumber) FROM Invoice WITH(UPDLOCK, HOLDLOCK) WHERE LocName = 'A'
第二个事务将被阻塞 "executing query" 等待第一个事务,直到您返回第一个窗口并执行COMMIT
或ROLLBACK
。 - Martin Smith