繁体   English   中英

获取数千个并发事务中的确切ID

[英]Get exact ID within thousands of concurrent transactions

我的桌子很拥挤,有成千上万的原木。 每次在数据库中插入新日志时,我都需要使用新日志的ID更新某些表。 因此,我使用这两行代码获取了最后一个ID:

objcon.execute "insert into logs (member,refer) values (12,12345)"
objcon.execute "select top 1 id from logs order by id desc"

恐怕第二行从最近的订单中获得另一个ID,因为在一秒钟内有成千上万的新日志。

这是一个示例场景,我知道有内置方法来获取最近插入的行的ID。 但是我的确切问题是,如果服务器(IIS和SQL Server)中的事务存在逻辑顺序,或者新事务在旧事务之前完成,那么第二行是否获得另一条日志的ID?

您的第二个查询肯定有可能从另一笔交易中获得ID。 我强烈建议您使用SCOPE_IDENTITY()。 在DBMS中提供了这种方法,仅用于此确切情况,即您插入一行然后从该表中选择最后一行,但是在这两次操作之间,其他连接可能会插入新行。

是。 并发事务可能会导致您尝试执行的操作出现问题。

正确的解决方案是output子句。 代码如下:

declare @ids table (id int);

insert into logs (member, refer)
    output inserted.id into @ids
    values (12, 12345);

select *
from @ids;

您可以在网上找到有关OUTPUT为什么更好的多个讨论。 原因如下:

  1. 您可以返回多个列,而不仅仅是标识。
  2. 这是会话和表安全的。
  3. 它处理多行。
  4. SELECTUPDATEDELETE语法相同。

如果未在SELECT查询上指定WHERE子句,则在提交更改之前,需要在事务中和SNAPSHOT隔离级别下执行这些查询。 这样,只有当前事务所做的更改才可见。

最好使用SCOPE_IDENTITY()返回在当前连接的最外部范围内生成的最后一个标识值。 这与@@IDENTITY不同,因为该值不受触发器的影响,触发器也可能会生成标识值。

objcon.execute "insert into logs (member,refer) values (12,12345)"
objcon.execute "select SCOPE_IDENTITY() AS id;"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM