SQL Server 序列线程安全吗? [英] Are SQL Server sequences thread safe?

查看:37
本文介绍了SQL Server 序列线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题太宽泛,但我找不到更具体的,请随时更换更好的.

Title is too broad but I couldn't find a more specific one, please feel free to change with better one.

我有一个使用序列而不是身份的表.我有三个同时插入表的生产者应用程序,一个消费者应用程序从未处理状态的表中选择,然后处理它们,最后更新已处理的行.

I have a table which is working with sequences instead identity. I have three producer applications which are concurrently insert into table, and a consumer application select from table whose status are not processed and then process them and finally update rows as processed.

消费者应用程序有一个规则,它不处理id(身份列值)小于最后自己处理的id的行

Consumer application has a rule that it does not process the row whose id (identity column value) is smaller than the id which lastly processed by itself

问题是,虽然我从来没有假设过会发生,但我的消费者应用程序在运行时就落入了这条规则.(为其他目的制定的规则).可视化;

The problem is, although I have never presumed to happen, my consumer application is falling into this rule while it is running. (Rule developed for other purposes). To visualize;

每个应用程序都会向数据库发送新数据,通常情况下,每个应用程序都应该由消费者选择并处理(轮询),但是有时(在工作期间内)我的表中总是有未处理的数据.

Each application sends new data to the database and under normal circumstances, each one should be selected by consumer and processed (polling), however sometimes (inside a working period) I always have an unprocessed data in my table.

这里是我的insert sp长什么样子,是生产者常用的;

Here what my insert sp looks like which is commonly used by producers;

CREATE PROCEDURE spInsData
    @Data VARCHAR(MAX)
AS
BEGIN
    SET @Id = NEXT VALUE FOR dbo.sequenceId

    INSERT INTO dbo.MyTable(Id, Data, Status)
    VALUES (@Id, @Data, 0)
END

所以我在想,生产者2和生产者3调用存储过程的时候,首先拿到的是序列值.然后,当涉及到插入时,不知何故,生产者 3 的插入发生得比生产者 2 快.然后消费者在处理较小的 id 之前处理较大的 id,因此永远不会处理 id 26.

So I am thinking of that when Producer 2 and Producer 3 calls the stored procedure, they first get the sequence values. Then, when it comes to insert, somehow Producer 3 insertion is occured faster than the Producer 2. Then the consumer processes the the bigger id before the smaller one, so id 26 is never processed.

我希望我清楚这个问题.可能是我解释的问题还是其他问题?如果是关于序列的,我是否可以为每个消费者锁定整个过程——获取序列并插入?

I hope I am clear about the problem. Could it be the problem as I explain or could it be something else? If it is about sequence, can I lock the whole process - get sequence and insert - for each consumer?

推荐答案

这称为竞争条件.从这个意义上说,序列(以及在持久化之前检索值的任何其他方法)是不安全的.

This is called race condition. In this sense sequences (and any other method which retrieves the value before persisting it) is not safe.

您希望将序列的下一个值作为 ID 列的默认约束:

You want to have the next value of the sequence as the default constraint for your ID column:

[id] INT NOT NULL CONSTRAINT [DF_MyTable_ID] DEFAULT NEXT VALUE FOR [dbo].[MySequence]

有了这个,新的序列值将在记录被持久化时生成.这本质上与 IDENTITY() 子句相同.

With this the new sequence value will be generated when the record is being persisted. This is essentially the same as an IDENTITY() clause.

这篇关于SQL Server 序列线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆