我有一个位置表,看起来像这样:
CREATE TABLE Locations (
Id INT NOT NULL AUTO_INCREMENT,
Name VARCHAR(255) NOT NULL,
NextInvoice INT NOT NULL,
PRIMARY KEY (Id)
);
现在我想为一个位置创建一张发票,我需要一个发票号。
发票编号将等于NextInvoice
该位置的值。然后我必须为下一张发票增加这个值。
非常简单的逻辑,但由于并发和竞争条件而变得复杂。
我如何执行检索某个位置的下一个可用发票编号然后递增该值的任务,并且在同时多次调用该代码时不重复或跳过任何数字?
我不能使用自动递增的唯一约束数,因为数字可以跨位置重复。
注意:我的核心技能包括 C#,不一定是 SQL-Server。事实上,我正在为此使用实体框架。但如果需要,我不会写一个存储过程。
如果分配发票编号的事务总是短期运行,并且您的吞吐量需求适中(几百张发票/秒),您可以使用序列表。它不应该是主要的“位置”表,因为行将经常(但短暂地)被独占锁定。所以
然后生成一个新的发票号
如果您的发票创建过程需要更长时间运行的事务,您可以根据需要预先生成尽可能多的 InvoiceNumber 并提交它们。
如果您需要为某个位置生成大量新的 InvoiceNumber,您可以将多个 1 添加到 NextInvoice,例如
set NextInvoice = NextInvoice + @numInvoices
。如果您确实需要高吞吐量,那么请在 Locations 中使用单个全局 SEQUENCE 对象或 IDENTITY 列,并放弃每个 Location 将有自己的发票编号的想法(即使数据模型允许)。