当前位置: 首页 > 面试题库 >

无需``身份''即可获取下一个ID号的最佳方法。

栾景胜
2023-03-14
问题内容

我必须在遗留数据库的表中插入一些记录,并且由于其他古代系统使用了该记录,因此更改表不是解决方案。

问题在于目标表具有int主键,但没有标识规范。因此,我必须找到下一个可用的ID并使用该ID:

select @id=ISNULL(max(recid)+1,1) from subscriber

但是,在执行此操作时,我想防止其他应用程序插入表中,以免出现任何问题。我尝试了这个:

begin transaction
    declare @id as int
    select @id=ISNULL(max(recid)+1,1) from subscriber WITH (HOLDLOCK, TABLOCK)
    select @id
    WAITFOR DELAY '00:00:01'
    insert into subscriber (recid) values (@id)
commit transaction
select * from subscriber

在SQL Management Studio中的两个不同的窗口中,一个事务始终作为死锁受害者被杀死。

我也SET TRANSACTION ISOLATION LEVEL SERIALIZABLE首先尝试了相同的结果…

关于如何确保我获得下一个ID并使用它而又不冒其他人(或我!)的危险的任何好的建议?

抱歉,您之前没有提到此内容,但这是一台SQL 2000服务器,因此我无法使用FOR UPDATE和OUTPUT之类的功能

更新 :这是为我工作的解决方案:

BEGIN TRANSACTION
    DECLARE @id int

    SELECT  @id=recid
    FROM    identities WITH (UPDLOCK, ROWLOCK)
    WHERE table_name = 'subscriber'

    waitfor delay '00:00:06'

    INSERT INTO subscriber (recid) values (@id)

    UPDATE identities SET recid=recid+1 
    WHERE table_name = 'subscriber'

COMMIT transaction

select * from subscriber

WAITFOR使我可以有多个连接,并多次启动查询以激发并发性。

感谢Quassnoi的回答以及所有其他贡献的人!惊人的!


问题答案:

创建另一个表:

t_identity (id INT NOT NULL PRIMARY KEY CHECK (id = 1), value INT NOT NULL)

如果只有一行,请锁定此行,并value在每次需要时将其递增一IDENTITY

要在单个语句中锁定,递增和返回新值,请使用:

UPDATE  t_identity
SET     value = value + 1
OUTPUT  INSERTED.value

如果您不想更新,只需锁定,然后发出:

SELECT  value
FROM    t_identity WITH (UPDLOCK, ROWLOCK)

这将锁定表直到事务结束。

如果您总是t_identity在弄乱之前先锁ancient_table,那么您将永远不会陷入僵局。



 类似资料:
  • 问题内容: 插入行的最佳方法是什么? 我知道和和,但不明白连接到每个利弊。 有人可以解释这些差异以及何时使用它们吗? 问题答案: 返回在所有范围内为当前会话中的任何表生成的最后一个标识值。 您需要小心 ,因为它是跨作用域的。您可以从触发器获取值,而不是当前语句。 返回为当前会话和当前范围中的任何表生成的最后一个标识值。 通常,您要使用什么 。 返回在任何会话和任何作用域中为特定表生成的最后一个标识

  • 我正在开发一个从Flickr中提取图像的应用程序,它还提供了上传到Flickr的能力。问题是Flickr API似乎不接受未经身份验证的照片上传。 换句话说,使用我的应用程序的最终用户必须通过Flickr网站,用他们的Flickr帐户登录并授予权限,只有在此之后,Flickr才开始上传过程。 谢谢

  • 我目前正在尝试使用社交媒体登录,并意识到这些登录的交付方式有点奇怪,这是因为我的工作场所和大多数办公室一样,将阻止第三方cookie作为安全策略。 Google Firebase身份验证使用第三方Cookie,因此,如果我尝试使用Firebase,我将被重定向到Google页面(如预期的那样),但当我在登录后重定向回原始网页(并且Firebase尝试设置Cookie)时,我会收到一个错误,说 然而

  • 问题内容: 什么是最好的实践方式得到一个唯一的机器ID 的架构? 除了地址,还有什么好办法吗? 问题答案: 根据您的内核,可以通过sysfs获得DMI信息。试试那些: 或使用工具

  • 问题内容: 我想在应用程序中连接到wifi网络。 码: 但是问题是我不知道。如何获取WiFi网络的SSID ? 问题答案: 如果您想获得所有可用的wifi: 如果要连接wifi ssid: 如果您想添加新的wifi设置,我已在下面编写了演示应用程序:

  • 问题内容: 首先,我并不是在寻找奇迹……我知道PHP是如何工作的,并且没有真正的方法可以在不使用加密的情况下向客户端隐藏我的代码。但这附带了要在正在运行的服务器上安装扩展的成本。 我正在寻找不同的东西…我不是要加密我的代码,甚至是对其进行混淆。有许多没有加密/混淆代码的PHP脚本,但它们是商业应用程序。例如,vBulletin和/或IP.Board论坛应用程序。 我只想知道这些人在他们的应用程序中