如何在Db2中创建并发安全且无间隙的计数器

问题描述:

我知道身份列和序列无法保证无间隙计数器,因为在回滚期间生成的数字会丢失。 所以我想保持我自己的计数器。
是对以下足以避免任何其他线程或系统(例如,数据共享)可潜在地与该更新/选择序列的干扰:如何在Db2中创建并发安全且无间隙的计数器

SELECT counter FROM FINAL TABLE (UPDATE cnt_table SET counter=counter+1 WHERE counter_id=?) 

或者是有一个更好的方式来创建这样的计数器?

以前,我想到了

SELECT counter FROM cnt_table WHERE counter_id=? FOR UPDATE OF counter WITH RS 
UPDATE cnt_table SET counter=counter+1 WHERE couner_id=? 

安全地增加计数器,同时避免并发事务甚至能够查询柜台,而第一笔交易没有完成的序列。然后我读到,在单个语句中带有UPDATE的SELECT FROM FINAL TABLE组合是更好的方法。那么它是否也会创建适当的锁定,以使并发事务等待?

注意:我在存储过程中使用动态SQL。该代码需要在Z上使用Db2 LUW和Db2。不需要分布式工作单元支持。

+3

由于事务回滚的风险,单靠数据库层无法保证无差距。它需要在应用层进行合作以确保无间隙和单调的计数器值,以便在发生数据库层回滚时(无论出于何种原因)进行恢复,特别是在分布式工作单元场景中。 – mao

+0

@mao,对不起,我不明白。递增计数器(假设从1到2)是交易的一部分。因此,如果事务回滚增量取消,下一个事务再次从1增加到2,直到这样的事务提交。我知道的唯一条件是事务需要保持一个锁(更新锁?),以便在第一个事务未完成时,没有并发事务甚至可以查询当前计数器的增量。所以我不明白为什么应用程序需要合作?
我还编辑了这个问题以提供更多的上下文(例如,不需要) –

+0

是否有任何性能要求或是“无间隙”的唯一要求?是否需要在MPP或数据共享/ pureScale中运行? –

(我以前发布的an answer for SQL Server有一些额外的比特,这应该是翻译)

嗯,它不会太大的关系,你选择哪个版本,因为该系统的主要担保人将是事务的隔离级别,而不是你是否有一个或两个语句。在某些方面,如果两者的基本机制相同,我不会感到惊讶。并且您希望在这里明确您的交易,以明确发生了什么。 (请注意,如果您已预先填入ID,则至少需要读稳定性,如果您没有预填ID,则可能为可重复读取)

请记住,在大多数情况下,从SELECT并不是最终结果 - 通常你至少要在一个表格中插入这个值,或者将它记录下来发送给某个地方(例如,收据邮寄程序 - 虽然在这种情况下失败更麻烦),其中任何一个都可能失败。在这些情况下,您很可能需要ROLLBACK

就我个人而言,我想我会使用change-table-reference,只是因为它使它更清洁。

+0

感谢您的见解。你基本上确认了我从文档中得出的结论:自我计数并确保正确的隔离。 我结束了两个单独的语句,导致没有人回答这个问题,如果'SELECT FROM FINAL TABLE(UPDATE ...)'自动设置所需的锁定,或者我必须扩展我的示例,以便它具有与两个单独的陈述... –