我有一个 DB2 表,其中包含要通过 MQ 发送到外部系统的大量记录。表中有一列包含记录状态(已发送或待发送)。
我编写了一个调度程序来不断检查表中是否有“待发送”的记录。如果是,程序将发送待处理的记录并相应地更新状态
该计划将在多个事务中启动。因此我期望同一个程序的多个实例将同时运行
我的问题是如何防止多个调度程序同时接收和发送相同的记录?
我被告知要使用带有行级锁的游标?但我不确定这是如何工作的
备注:我正在 z/os 环境中研究 CICS COBOL
我有一个 DB2 表,其中包含要通过 MQ 发送到外部系统的大量记录。表中有一列包含记录状态(已发送或待发送)。
我编写了一个调度程序来不断检查表中是否有“待发送”的记录。如果是,程序将发送待处理的记录并相应地更新状态
该计划将在多个事务中启动。因此我期望同一个程序的多个实例将同时运行
我的问题是如何防止多个调度程序同时接收和发送相同的记录?
我被告知要使用带有行级锁的游标?但我不确定这是如何工作的
备注:我正在 z/os 环境中研究 CICS COBOL
我认为你有一个设计问题。我们通过在 DB2 表上设置一个触发器来完成类似于您尝试做的事情,该触发器将 MQ 消息发送到定义为触发 CICS 事务的队列。
在您的情况下,您可能可以完全放弃 CICS,只需按照@BillWoodger 的建议进行操作,并在设置挂起标志时发送消息。
一种方法如下 1) 确定大型 DB2 表的集群索引 2) 然后运行程序的不同实例,只查看该集群索引的不同部分。例如,如果集群索引位于唯一的数字 ID 字段上,例如帐户 ID,并且 ID 大小为整数 9,则实例一查看帐户 ID 范围从 0 到 099999999,实例 2 查看帐户 ID 范围从 100000000 到 1999999999和 .....
通过这种方式,您可以编写您的 cusror 并根据需要执行更新和提交。
CICS 将为您协调与 DB2 的 SQL 事务。您运行的每个 CICS 事务都能够选择和锁定更新行,并且 DB2 可以在所有这些事务之间进行协调,如果您做两件事,就可以防止选择多条记录。
当您读取符合条件的行时,使用 SELECT FOR UPDATE 类型的操作,这将锁定您检索的每一行并防止其他并发事务访问同一行(也需要您使用行级锁绑定,除非您希望锁定整页,请参阅您的 DBA 关于基于行大小的选项)。
在释放记录或结束 CICS 事务之前,您必须做一些事情来将所述记录标记为“已发送”,以便其他等待的并发事务不会抓取它们并再次发送它们。这可以像在表中添加一个已发送的 Y/N 列并将“AND sent <> 'Y'”添加到您的 select where 子句一样简单。发送记录后,对这些记录执行 UPDATE 并设置 sent = 'Y'。根据您的行数据,您可能会使用其他内容,例如发送时间或其他内容,它只需要将所述行排除在重新选择之外。