阻止表中的并行插入

时间:2019-02-13 01:34:33

标签: sql sql-server

有没有办法阻止表中的并行插入而不仅仅是行锁级别?

插入速度非常快(毫秒级),但是我想保证某种特定的毫秒条目只能插入1行。

通过设计,它已经确保数据永远不会不一致(请参见load_id_by_date):

CREATE TABLE my_table
(
    load_id          uniqueidentifier NOT NULL,
    load_date        datetime NOT NULL DEFAULT (GETDATE()),
    load_id_by_date  bigint NOT NULL DEFAULT (CAST(GETDATE() as decimal(19,9)) * 1000000000) UNIQUE,
    is_processed     bit DEFAULT(0)
    PRIMARY KEY (load_id_by_date)
)

但是我只是想知道是否有一种方法可以阻止多线程调用中发生并行插入。下面一个简单的(单线程)模拟突出显示了这个问题。

-- TO TEST:
WHILE (1=1)
BEGIN
    INSERT INTO my_table (load_id)
    SELECT NEWID()
END

将有

Msg 2627, Level 14, State 1, Line 6
Violation of UNIQUE KEY constraint 'UQ__config_l__A307163DB6D0D819'. Cannot insert duplicate key in object 'my_table.config_load_id_toprocess'. The duplicate key value is (43507564143441).

但是现在我正在考虑采用时间戳唯一性方法可能是错误的方法。但是实际的调用速度并不会那么快,最快的频率是2秒,但是是多线程的。

1 个答案:

答案 0 :(得分:1)

感谢@Mitch Wheat的XY问题。我已经缩小了工作范围。

现在,根据NEWID()的bigint表示生成load_id_by_int(以前称为load_id_by_date)。冲突的可能性现在是可以接受的(至少在我看来)。感谢大家的评论。

CREATE TABLE my_table
(
    load_id          uniqueidentifier NOT NULL,
    load_date        datetime NOT NULL DEFAULT (GETDATE()),
    load_id_by_int   bigint NOT NULL DEFAULT (ABS(convert(bigint, convert (varbinary(8), NEWID(), 1)))),
    is_processed     bit DEFAULT(0)
    PRIMARY KEY (load_id_by_int)
)

该概念源自Convert from UniqueIdentifier to BigInt and Back?