Tsql 最大值+;并行事务中的1个主键

Tsql 最大值+;并行事务中的1个主键,tsql,Tsql,1)我知道身份和自动递增,我支持这101%,但有时,你没有选择(如遗留系统/政治) 您好,假设我有一个insert语句,如下所示: insert into SomeTable select (select coallesce(max(ID),0)+1 from SomeTable), @ParameterValue 现在,我有两个应用程序采用cmd line参数并执行以下操作: // Begin Transaction with isolation level ReadUn

1)我知道身份和自动递增,我支持这101%,但有时,你没有选择(如遗留系统/政治)

您好,假设我有一个insert语句,如下所示:

insert into SomeTable
select (select coallesce(max(ID),0)+1 from SomeTable),
       @ParameterValue
现在,我有两个应用程序采用cmd line参数并执行以下操作:

//    Begin Transaction with isolation level ReadUncommited
for(i=0; i<100000; i++)
    // Run the insert statement with the cmd line parameters
//    Commit Transaction
我试图通过以下方式实现这一目标:

insert into SomeTable with (tablock) - doesnt work, first one app finishes, then the other one

insert into SomeTable with (udplock) - i get PK violation
我慢慢地变得绝望了。所以,问题是,是否存在某种锁,它只在语句期间锁定表,但不保持到事务结束

多谢各位


哦,可以肯定的是,id之间的空格不是问题

您可以将事务移动到循环内部并使用可重复读取
但这会影响响应时间

for(i=0; i<100000; i++) 
{
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    GO
    BEGIN TRANSACTION;
    GO
    insert into SomeTable  
    select (select coallesce(max(ID),0)+1 from SomeTable), @ParameterValue
    GO
    COMMIT TRANSACTION;
    GO
}

对于(i=0;iSorry),这是行不通的。事务必须在外部进行。这是从实际问题简化而来的,有几个“接口”(.exe应用程序)正在运行,可以将数据导入/导出到DB/文件。我想获得一些接口(即,命令接口和客户接口同时运行,但它们都可以使用非标识主键写入同一个表)并且我不希望一个接口在开始时停止,然后等待另一个接口。rry,这不可能让一个事务和两个事务中的循环得到“正确的”由于需要提交另一个insert,所以需要从另一个insert中获取值。此外,还需要计算(查询)每次插入的新maxvalue。唯一的执行方式是一个循环完全阻止另一个循环。您能否尝试降低循环迭代次数以加快阻止时间?我不知道传统系统如何工作以及您可以对其进行更改,但对于运行多个可执行程序的场景,这更像是一个“消息”问题。理想的解决方案是不在表中直接插入,而是在队列中插入,并让一个类似单例的进程来处理任务,从而从队列到达目标表。当然,如果您需要立即从插入中获得反馈(例如:如果您需要知道生成的Id)这似乎是个问题。最后一句话:有一个“黑客”可以帮助您。由于您自己生成Id,您可以通过插入不同的值来避免PK冲突。如果您有两个可执行文件,一个可以插入对值,另一个可以插入赔率值。如果您有10个可执行文件,每个可执行文件都可以插入一个完成时间为0..9的Id,依此类推。这不是一种优雅的解决方法,但可以奏效(并产生大量维护难题)@jean你知道你是在评论一个答案。这不是我的传统系统。我也不知道它是如何工作的。只是一个建议,但查询提示是…提示而不是规则,引擎没有义务遵循它。事实上,你可以分析锁是如何升级的。这里也有并发,一个事务会阻止另一个事务在某种程度上,您可以尝试在循环内隔离插入,但这很可能会执行糟糕的操作
for(i=0; i<100000; i++) 
{
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    GO
    BEGIN TRANSACTION;
    GO
    insert into SomeTable  
    select (select coallesce(max(ID),0)+1 from SomeTable), @ParameterValue
    GO
    COMMIT TRANSACTION;
    GO
}