我想在并行在线事务中大量使用的DB2表上放置DB2 Triggers for Insert,Update和Delete。这些表由Sysplex,DB2 Version 10上的几个成员共享。 在每个DB2触发器中,我想在一个中心表中插入一行,然后让一个后台进程调用一个存储过程来每秒读取一次这个表来处理新插入的行,按顺序排序insert(序列号或时间戳)。 我非常关注DB2索引锁定争用,并希望确保我不会使用这些触发器向应用程序引入死锁/超时。
显然,我会利用DB2 Features来减少像行级别锁定一样的锁定,但仍然没有看到如何避免索引争用的真正好方法。
我看到三个不同的选项来选择新插入的行。
SELECT COLUMN_1,.... Column_n 来自CENTRAL_TABLE 在哪里SEQ_NO> “最后序列号码” 由SEQ_NO开始;
锁定级别必须是CS,以避免选择未更新的行,稍后将回滚。 我想我需要一个带有SEQ_NO ASC
的索引Pro:后台进程只读取行并且不进行更新/删除(仅限共享锁) 否:由于使用了升序密钥而导致索引争用。 我可以稍后清理处理过的记录(例如通过滚动分区)。
SELECT COLUMN_1,.... Column_n 来自CENTRAL_TABLE WHERE STATUS ='未处理' 订购TIMESTAMP;
稍后我会将所选行的STATUS更新为“已处理” 我想我需要一个状态索引 Pro:索引中没有递增的序列号,也没有直接删除 缺点:在线交易和后台流程的并发更新 清理工作将在非工作时间进行
SELECT COLUMN_1,.... Column_n 来自CENTRAL_TABLE 订购TIMESTAMP;
由于该表包含的记录非常少,因此不需要可以创建热点的索引。 另外我认为我可以使用Isolation Level UR进行SELECT,因为我会在以后删除此行时检测到潜在的未提交数据。 对于主键索引,我可以使用GENERATE_UNIQUE,它是随机的而不是升序。 Pro:没有索引热点,插入可以通过随机UNIQUE_ID分布在表空间中 Con:表空间扫描并对存储过程的每次调用进行排序,并与在线插入并行删除记录。
期待社区对此问题的看法。这必须是一个非常常见的问题,例如SAP在其批输入表上应该有类似的问题。 我倾向于支持选项3,因为它避免了索引争用。 可能还有另一种解决方案在你脑海里。
答案 0 :(得分:0)
我认为您的各种解决方案会遇到很多性能问题。 (我知道过早的优化是一种罪恶,但经验告诉我们,有些事情在繁忙的系统中无法发挥作用)。
您应该能够使用DB2s自动增量功能来获取序列号,而对性能影响很小或者知道。
对于其他人,您可能应该看一下基于队列的解决方案。
让你的触发器将操作(INSERT / UPDATE / DELETE)和行的键放入MQ队列,
然后有一个长时间运行的背景任务(在CICS?)做你的后期处理,因为它处理一次更新,你不应该自己绊倒。拥有一个能够批量处理工作单元的单个加载和活动任务应该可以为您提供每秒3到500次更新的吞吐量。