无间隙序列,其中涉及具有多个表的多个事务

时间:2014-03-22 13:06:35

标签: c# sql-server oracle postgresql transactions

我(根据法律)要求在不同的表格上使用无间隙数字。 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_SequenceDocument_Sequence的顺序错误。

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

我该如何处理?

我已经看到建议你“锁定”序列,直到事务被提交或回滚,但是当涉及这么多表并且这个复杂的长事务时,这将是系统的一个巨大停顿。

4 个答案:

答案 0 :(得分:6)

正如您似乎已经得出的结论,无间隙序列根本无法扩展。您可能会在发生回滚时冒着丢弃值的风险,或者您有一个序列化点可以阻止多用户并发事务系统进行扩展。你不能兼得。

我的想法是,后期处理行动怎么样,每天,你有一个在业务结束时运行的流程,检查差距,并重新编号需要重新编号的任何东西?

最后一个想法:我不知道你的要求,但是,我知道你说法律要求这是""。那么,问问自己,在有电脑之前人们做了什么?这个"要求"遇到了?假设你有一堆空白表格预先印有"序列"右上角的数字?如果有人在那个表格上洒咖啡会怎么样?怎么处理?看来你需要一个类似的方法来处理你的系统。

希望有所帮助。

答案 1 :(得分:3)

原则上无法解决此问题,因为任何事务都可以回滚(错误,超时,死锁,网络错误......)。

拥有一个串行争用点。尝试尽可能减少争用:保持分配数量尽可能小的交易。此外,在事务中尽可能晚地分配数字,因为只有在您分配数字争用时才会出现。如果你正在进行1000毫秒的无竞争工作,然后分配一个数字(需要10毫秒),你仍然有100度的并行度就够了。

所以也许你可以插入虚拟序列号的所有行(你说有很多行),并且只在事务结束时你快速分配所有实际序列号并更新已经写入的行。如果有更多插入而不是更新,或者更新比插入更快(它们将是插件),或者插入之间存在其他处理或等待交错,这将很有效。

答案 2 :(得分:2)

无差距序列很难得到。我建议改用普通serial列。使用窗口函数row_number()创建一个视图以生成无间隙序列:

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

答案 3 :(得分:0)

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

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

  2. 将MASTER_TABLE中所有内部参照完整性的哑唯一标识符用于其他相关详细信息表。

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

  4. 所有需要在屏幕或报告或其他任何内容上显示无间隙序列号的查询都会将MASTER_TABLE与无间隙附加属性第4范式表格连接起来。注意,只有在后台线程填充了无间隙附加属性第4范式表后,才会满足这些连接。