postgresql生成无间隙序列
我必须/必须为发票创建唯一ID。我有一个表id和另一列来表示这个唯一的数字。我使用序列化隔离级别。使用postgresql生成无间隙序列,sql,postgresql,Sql,Postgresql,我必须/必须为发票创建唯一ID。我有一个表id和另一列来表示这个唯一的数字。我使用序列化隔离级别。使用 var seq = @"SELECT invoice_serial + 1 FROM invoice WHERE ""type""=@type ORDER BY invoice_serial DESC LIMIT 1"; 没有帮助,因为即使使用FOR UPDATE,它也不会像序列化级别那样读取正确的值 唯一的解决方案似乎放了一些重试代码 您可以创建一个没有缓存的序列,然后从序列中获取下
var seq = @"SELECT invoice_serial + 1 FROM invoice WHERE ""type""=@type ORDER BY invoice_serial DESC LIMIT 1";
没有帮助,因为即使使用FOR UPDATE,它也不会像序列化级别那样读取正确的值
唯一的解决方案似乎放了一些重试代码 您可以创建一个没有缓存的序列,然后从序列中获取下一个值并将其用作计数器
CREATE SEQUENCE invoice_serial_seq START 101 CACHE 1;
SELECT nextval('invoice_serial_seq');
更多信息您可以将表锁定为插入,和/或需要有重试代码。没有其他选择。如果您停下来思考以下情况会发生什么:
您将看到原因。序列不会生成无间隙的数字集,而且确实没有办法让它们这样做,因为回滚或错误将“使用”序列号 我不久前写了一篇关于这方面的文章。它是针对Oracle的,但实际上是关于无缺口数字的基本原则,我认为在这里也是如此 嗯,又发生了。有人知道如何实现一个需求来生成一个无间隙的数字序列,一群反对者突然对他们说(这里我稍微解释一下)这会破坏系统性能,这很少是一个有效的需求,写这个需求的人都是白痴 正如我在文章中指出的,有时生成无间隙的数字序列是真正的法律要求。英国200多万家增值税(增值税)注册机构的发票号码有这样的要求,其原因相当明显:这使得隐藏税务机关的收入来源变得更加困难。我看到有评论说这是西班牙和葡萄牙的一项要求,如果这不是许多其他国家的要求,我也不会感到惊讶 那么,如果我们接受这是一个有效的要求,在什么情况下,无间隙数列*是一个问题?集体思考通常会让你相信它总是存在的,但事实上,它只是在非常特殊的情况下的一个潜在问题
insert into
invoices
(
invoice#,
...)
with curr as (
select Coalesce(Max(invoice#)) max_invoice#
from invoices)
select
curr.max_invoice#+rownum,
...
from
tmp_invoice
...