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