涉及多个表的多个事务的无间隙序列

问题描述 投票:0回答:4

我(根据法律)要求在不同的桌子上显示无间隙的数字。 ID 上可以有洞,但序列上不能有洞。

这是我必须在 C# 代码或数据库(Postgres、MS SQL 和 Oracle)中解决的问题。

这是我的问题:

Start transaction 1

Start transaction 2

Insert row on table "Portfolio" in transaction 1

Get next number in sequence for column Portfolio_Sequence (1)

Insert row on table "Document" in transaction 1

Get next number in sequence for column Document_Sequence (1)

Insert row on table "Portfolio" in transaction 2

Get next number in sequence for column Portfolio_Sequence (2)

Insert row on table "Document" in transaction 2

Get next number in sequence for column Document_Sequence (2)

Problem occurred in transaction 1

Rollback transaction 1

Commit transaction 2

问题:

Portfolio_Sequence
Document_Sequence
的序列存在间隙。

请注意,这非常简化,并且每个事务中包含更多的表。

我该如何处理这个问题?

我已经看到建议“锁定”序列,直到事务提交或回滚,但是当涉及如此多的表和如此复杂的长事务时,这对系统来说将是一个巨大的停止。

c# sql-server oracle postgresql transactions
4个回答
6
投票

正如您似乎已经得出的结论,无间隙序列根本无法扩展。要么在发生回滚时面临删除值的风险,要么您的序列化点将阻止多用户并发事务系统扩展。你不能两者兼得。

我的想法是,后处理操作怎么样?每天,您都有一个在营业结束时运行的流程,检查间隙,并对需要重新编号的任何内容进行重新编号?

最后一个想法:我不知道您的要求,但是,我知道您说这是“法律要求”。好吧,问问你自己,在计算机出现之前人们做了什么?如何满足这个“要求”?假设您有一叠空白表格,右上角预先印有“序列”号?如果有人把咖啡洒在表格上会发生什么?那是怎么处理的?看来你需要一个类似的方法来在你的系统中处理这个问题。


3
投票

这个问题原则上不可能解决,因为任何事务都可以回滚(错误、超时、死锁、网络错误……)。

将会有一个串行争用点。尝试尽可能减少争用:使分配数字的事务尽可能小。另外,在交易中尽可能晚地分配号码,因为只有在分配号码时才会出现争用。如果您正在执行 1000 毫秒的无竞争工作,然后分配一个数字(花费 10 毫秒),您仍然拥有 100 的并行度,这已经足够了。

因此,也许您可以使用虚拟序列号插入所有行(您说有很多行),并且只有在事务结束时,您才能快速分配所有真实序列号并更新已写入的行。如果插入比更新多,或者更新比插入快(它们将会如此),或者在插入之间有其他处理或等待交错,那么这将很有效。


3
投票

无间隙序列很难获得。我建议改用普通的

serial
列。使用窗口函数
row_number()
创建视图以生成无间隙序列:

CREATE VIEW foo AS
SELECT *, row_number() OVER (ORDER BY serial_col) AS gapless_id
FROM   tbl;

0
投票

这是一个应该同时支持高性能和高并发的想法:

  1. 使用高度并发的缓存 Oracle 序列为无间隙表行生成哑唯一标识符。将此实体称为 MASTER_TABLE

  2. 使用哑唯一标识符来确保从 MASTER_TABLE 到其他相关详细信息表的所有内部引用完整性。

  3. 现在,您的无间隙 MASTER_TABLE 序列号可以作为 MASTER_TABLE 上的附加属性来实现,并将由与 MASTER_TABLE 行创建分开的进程填充。事实上,无间隙附加属性应该维护在 MASTER_TABLE 的第四范式属性表中,因此单个后台线程可以随意填充它,而不用担心 MASTER_TABLE 上的任何行锁。

  4. 所有需要在屏幕或报告等上显示无间隙序列号的查询都将使用无间隙附加属性第四范式表连接 MASTER_TABLE。请注意,只有在后台线程填充无间隙附加属性第四范式表后,这些连接才会得到满足。

© www.soinside.com 2019 - 2024. All rights reserved.