SQL Server竞争条件问题
(注意:这适用于MS SQL Server) 假设您有一个带有主键标识列和CODE列的表ABC.我们希望这里的每一行都有一个独特的,顺序生成的代码(基于一些典型的校验位公式). 假设您有另一个表DEF只有一行,它存储下一个可用的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声明来模拟延迟,因此可以很容易地看到竞争条件.我认为关键问题是我对交易如何运作的错误认识. 解决方法将事务隔离级别设置为Serializable.在较低的隔离级别,其他事务可以读取此事务中读取(但尚未修改)的行中的数据.因此,两个事务确实可以读取相同的值.在隔离度非常低(Read Uncommitted)时,其他事务甚至可以在修改后(但在提交之前)读取数据… 查看有关SQL Server隔离级别here的详细信息 因此,底线是隔离级别在这里是一个重要的部分来控制其他事务进入这个访问的访问级别. 注意.从link开始,关于Serializable begin tran declare @x int update def set @x= nextcode,nextcode += 1 waitfor delay '00:00:15' select @x commit tran (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |