假设 SQL Server 表有两MailID
列,最大值 = 5。
如果两个不同的用户在同一时间执行INSERT,尝试插入查询Max(MailId)+1
到MailID
列,是有可能,这两个新行可能获得的价值6?
我想了解 SQL Server 如何在内部同时处理多个请求。
gbn*_*gbn 13
是的,这是可能的(根据 JNK 的回答:2 个重叠的MAX 读取,都得到 6 个,一个失败,重复假设约束)
正是出于这个原因,使用 IDENTITY 列。
如果您有一些不使用 IDENTITY 的奇怪想法,那么您必须使用锁粒度 (TABLOCKX) 或信号量 (sp_getapplock) 来限制并发性并一次只允许一个进程运行 MAX。
编辑:
同时(或非常接近)传入的两个请求并发运行。它们彼此分开但重叠。
所以每个进程都会使用 MAX 读取表,并且都得到 6。此时,进程和读取以及 INSERT 都还没有开始。
领先进程插入 6,紧随其后的是滞后进程。滞后过程将得到唯一键违规(您有唯一性,对吗?)
如果进程之间的差距足够大,以便在第一次 INSERT之后进行第二次读取,那么您就可以了。
然而,如果你有足够多的调用,你有这种重复的风险,那么使用锁/信号量来减少并发是疯狂的......
如果没有限制来防止重复,它将允许两者。
使用Identity
我在关于类似主题的其他问题中推荐的字段。
如果有约束,那么其中一个将比另一个早一毫秒。认为他们会恰好在同一时间是不现实的。第一个将执行插入,第二个将等待第一个锁定到位。一旦第一个释放锁,第二个将尝试插入并在重复密钥插入时失败。
归档时间: |
|
查看次数: |
15104 次 |
最近记录: |