如何在表的单行中存储、检索和更新序列号,其架构如下:
ID (int)
LookUp(varchar)
SeqNum(int) --business logic dictates the SeqNum is constrained to a particular range, say 1300 to 7600
对我来说,这看起来就像棒球场的答题器计数器人员使用答题器为每个经过的人打勾。我希望每个人都有一个唯一的号码。我希望多个点击器计数器人员使用同一个点击器,并且我不希望丢失任何值。
到目前为止,我的方法要么导致死锁情况,导致表无法访问,要么我绞尽脑汁想知道如何构造一个存储过程,该存储过程调用一个具有事务来锁定记录、读取记录、更新记录的存储过程,提交交易,并解锁记录在伪代码中我尝试了类似的东西
从存储过程中:
Call getnum stored procedure
sproc getnum
begin trans
select current seqnum into a variable from Seqtbl where lookupval = 'nosebleed'
update Seqtbl.seqnum++ where lookupval = 'nosebleed'
end trans
我想添加一个 bool 列bLock
,然后让 getnum 存储过程检查值是否= false,然后更新锁(bLock=true),然后读取、更新和更新不使用事务锁定 (bLock = false)。但我不相信多个进程的考虑不周的时间安排不会相互干扰。
我确实看到其他人使用标识列来实现类似的解决方案,但这些方法似乎需要每个 LookUp(来自上面的示例架构)值一个表。
是否有人提供建议、用于解决类似问题的策略、指导或链接,让我了解 SQL Server 需要了解此场景的解决方案的重要方面?
最佳答案
如果你只使用单个语句,你应该摆脱死锁:
declare @id int
update Seqtbl
set @id = seqnum, seqnum = seqnum + 1
where lookupval = 'nosebleed'
这里更大的问题是你说序列中不能有漏洞。如果您的实际事务可以回滚,那么您必须将提取到要回滚的同一事务的序列包含在内,这可能会导致大量阻塞,具体取决于调用的数量。
如果您使用的是 SQL Server 2012 或更高版本,您还应该查看序列对象,但这也无法解决缺少值的问题。
关于sql - 在 SQL Server 2008 中存储、检索和更新表的单行中的序列号(数据类型 int),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28264465/