【问题标题】:z/os cics db2 cobol program to process database entries concurrentlyz/os cics db2 cobol 程序同时处理数据库条目
【发布时间】:2015-06-20 08:24:49
【问题描述】:

我有一个 DB2 表,其中包含要通过 MQ 发送到外部系统的大量记录。表中有一列包含记录状态(已发送或待发送)。

我编写了一个调度程序来不断检查表中是否有“待发送”的记录。如果是,程序将发送待处理的记录并相应地更新状态

该计划将在多个事务中启动。因此,我预计同一程序的多个实例将同时运行

我的问题是如何防止多个调度程序同时拾取和发送相同的记录?

有人告诉我将游标与行级锁一起使用?但我不确定这是如何工作的

备注:我正在 z/os 环境下做 CICS COBOL

【问题讨论】:

  • 与其浪费资源不断地启动一些东西来查看数据库,不如在执行“待处理”时不直接执行 MQ?您如何看待“调度程序”程序?
  • @BillWoodger 背后有一段很长的故事。发出的消息将得到计数器系统的确认。有发送消息的阈值。假设有 500 条消息正在发送但没有确认,我们将需要停止发送更多消息。所以有一些逻辑来确定和发送消息。但是多个实例使情况变得复杂
  • 您需要使用所有相关信息更新您的问题(使用问题下方的编辑链接)。我们不能做整个设计,因为我们不知道一切。编写自己的“调度程序”非常复杂,而且很难在不影响其他处理的情况下完成。自动触发无限多个任务是个坏主意。 Checker 和 doer 甚至访问相同的数据。如果您在队列中有记录,您可以随时检查并在必要时重新排队。

标签: concurrency db2 cobol zos cics


【解决方案1】:

CICS 将为您协调与 DB2 的 SQL 事务。您运行的每个 CICS 事务都将能够选择和锁定更新行,并且 DB2 可以在所有这些事务之间进行协调,并且如果您做两件事,就可以防止选择多条记录。

当您读取符合条件的行时,使用 SELECT FOR UPDATE 类型的操作,这将锁定您检索的每一行并防止其他并发事务访问同一行(也需要您使用行级锁绑定,除非您想要整页锁定,请咨询您的 DBA,了解基于行大小的选项)。

在您释放记录或结束 CICS 事务之前,您必须将所述记录标记为“已发送”,以便其他等待的并发事务不会抓取它们并再次发送它们。这可以像在表中添加一个已发送的 Y/N 列并将“AND sent 'Y'”添加到您的 select where 子句一样简单。发送记录后,对这些记录执行 UPDATE 并设置 sent = 'Y'。根据您的行数据,您可能会使用其他内容,例如发送时间或其他内容,它只需要将所述行排除在重新选择之外。

【讨论】:

    【解决方案2】:

    我认为你有一个设计问题。我们通过在 DB2 表上设置一个触发器来完成与您尝试做的类似的事情,该触发器将 MQ 消息发送到定义为触发 CICS 事务的队列。

    在您的情况下,您可以完全放弃 CICS,只需按照@BillWoodger 的建议进行操作,并在您设置挂起标志时发送消息。

    【讨论】:

      【解决方案3】:

      一种方法如下 1)确定DB2大表的Clustering index 2) 然后让程序的不同实例运行,只查看这个集群索引的不同部分。例如,如果集群索引位于唯一的数字 ID 字段上,例如帐户 ID,并且 ID 大小为整数 9,则实例一查看帐户 ID 范围从 0 到 099999999,实例 2 查看帐户 ID 范围从 100000000 到 1999999999还有.....

      通过这种方式,您可以编写您的 cusror 并根据需要执行更新和提交。

      【讨论】:

        猜你喜欢
        • 2012-05-02
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-12
        • 2016-12-16
        • 2020-10-26
        • 1970-01-01
        相关资源
        最近更新 更多