(注:以下内容适用于 MS SQL Server)
假设你有一个带有主键身份列和CODE列的表ABC,我们想让每一行都具有基于某种典型校验位公式的唯一、顺序生成的代码。
假设你还有另一张表DEF,只有一行数据,用于存储下一个可用的CODE(可以想象成简单的自动编号)。
我知道像下面这样的逻辑会出现竞争条件,在此情况下两个用户可能会得到相同的CODE:
1) Run a select query to grab next available code from DEF
2) Insert said code into table ABC
3) Increment the value in DEF so it's not re-used.
我知道两个用户可能会被困在步骤1,并最终在ABC表中得到相同的CODE。如何处理这种情况?我认为我可以在此逻辑周围加上“begin tran”/“commit tran”,但我认为那并没有起作用。我有一个存储过程来测试,但当我在MS的两个不同窗口中运行时,我无法避免竞争条件。begin tran
declare @x int
select @x= nextcode FROM def
waitfor delay '00:00:15'
update def set nextcode = nextcode + 1
select @x
commit tran
有人可以给我解释一下吗?我认为事务会防止其他用户在第一个事务完成之前访问我的NextCodeTable,但我想我的事务理解是错误的。
编辑:我尝试将等待移到“更新”语句之后,然后我得到了两个不同的代码…但我怀疑。 我在那里使用waitfor语句来模拟延迟,以便轻松看到竞争条件。 我认为关键问题是我对事务工作方式的错误理解。