如果大约 50 个用户试图更新 DB2 表中的相同字段,CICS 将如何处理这个问题?这在 COBOL DB2 程序中是如何处理的?
2 回答
当 CICS 伪会话程序与 DB/2 交互以更新数据库时,必须注意管理数据完整性,尤其是当多个 CICS 事务可能试图几乎同时读取/更新同一个 DB/2 表行时。
下面是对伪会话 CICS 事务的常见设计模式的非常简化的解释(这是 CICS 最常见的交互式编程模式类型)。这个问题的答案: what-are-the-advantages-of-pseudo-conversational-vs-conversational-cics-programm简要概述了伪对话 cics 的工作原理,您可能需要在继续之前查看此内容...
伪会话 CICS 事务旨在从 COMMAREA(事务之间持续存在的一块内存)中获取它们当前的运行状态。程序使用 COMMAREA 中保存的状态来确定下一步需要做什么。然后它执行它,确定下一个状态应该是什么,将新状态和它可能需要“记住”的任何数据保存到 CICS COMMAREA 中,然后它退出 - 释放所有资源,包括它持有的任何 DB/2 锁.
面对多个竞争相同数据库行的选择/更新/插入/删除事务,DB/2 锁是保持数据库完整性的关键。伪会话 CICS 的问题在于,在事务从表中获取其数据到需要更新表的时间之间,这些锁会丢失。
典型的伪会话 CICS 事务可能经历的状态类似于:
- Initial - 开始新的交易,要求用户输入关键数据(将下一个状态设置为Display)
- 显示- 验证在初始状态输入的密钥。从 DB/2 检索相关数据并显示(将下一个状态设置为Commit)
- 提交- 从显示状态验证更改的数据并更新 DB/2(将下一个状态设置为Initial)
请注意,在Display期间检索数据。此时 DB/2 使用读取锁来防止其他事务在读取行时更新该行。根据 DB/2 和您的 DML 的配置方式,此锁可能仅在显示阶段期间或在检索行时才有效。在任何一种情况下,一旦程序退出,该锁就会丢失。当程序再次重新启动时,它将处于提交状态,准备好执行适当的 DB/2 更新/插入 DML 以实现对数据库的请求更改。
因为在这些状态转换之间没有持久的 DB/2 锁,所以没有什么可以阻止另一个事务在第一个事务显示和更新之间访问或更改数据。这可能导致严重的数据完整性问题。请注意,当事务处于活动状态时,它可能持有 DB/2 锁,从而有效地阻止其他事务读取未提交的更新或更新它正在“查看”的行 - 但它不能在“对话”的调用之间持有这些。
程序员用来在伪会话 CICS 事务过程中维护数据完整性的常用机制是让所有事务依赖于单个公共可更新资源来充当更新冲突检测器。例如,如果您的数据库正在管理与您的客户相关的数据,则可能有一个通用的唯一键用于识别任何给定的客户。这些唯一键通常只是一个数字或短字符串(例如 Customer-Id)。客户数据库的所有表中的所有行都可能使用相同的通用唯一键来标识特定客户(毕竟这就是键的全部含义)。
创建一个包含两列的 TRANSACTION 表,一列用于 Customer-Id,另一列用于某些事务唯一标识符,这通常只是事务开始时生成的时间戳(也可以是任务 ID,它只需要对事务来说是唯一的)。将此事务标识符称为 TRANS-KEY。当进入交易的显示阶段时,交易第一次具有客户 ID。然后,它使用其 TRANS-KEY 更新此 Customer-Id 的 TRANSACTION 表。两者都保存到 COMMAREA。请注意,这里的更新仅基于 Customer-Id,它将用自己的唯一值替换当前的 TRANS-KEY。进入显示阶段,用户输入他们的更改并提交阶段进入。此时,事务尝试根据其保存的 Customer-id 和 TRANS-KEY 更新 TRANSACTION 表。如果更新失败,则事务“知道”某个其他事务已开始对同一客户进行处理(另一个事务更改了相同客户 ID 的 TRANS-KEY,因此当前事务遇到超时或未找到行错误) . 为了保持数据库完整性,当前事务必须退出。它将向用户显示某种消息,通知他们已请求并发更新并且必须放弃请求的更新。另一方面,如果给定 Customer-id 的 TRANS-KEY 未更改,则将获取数据库锁,以防止任何其他事务更改同一 Customer-Id 的该行。
完成所有这些工作的关键是更新 Customer 数据库的所有事务都使用相同的 TRANSACTION 表来检测并发更新尝试。
此处描述的资源锁定机制通常称为“冲突检测”,它只是在伪会话 CICS 事务过程中保持数据库完整性的许多可能方法之一。关键点是 DB/2 锁在事务过程中被多次获取和删除,并且 DB/2 锁管理器、CICS Syncpoint 管理器和应用程序本身之间需要一些“合作”才能在使用时保持数据库完整性伪会话 CICS。
最后,实际更新数据库的事务将是最后一个检索数据的事务——所以这个故事的寓意是迟到早完成!
上面的讨论不是特定于 COBOL 的,它适用于所有编程语言,包括 COBOL,用于使用 DB/2 和伪会话 CICS 开发应用程序。
从 IBM 手册中,CICS 如何连接到 DB2:
CICS® DB2® 附件工具随 CICS 一起提供。CICS DB2 附件工具为 CICS 应用程序提供了在 CICS 环境中操作时对 DB2 数据的访问。因此,CICS 应用程序可以访问 DB2 数据和 CICS 数据。如果发生事务或系统故障,CICS 会协调 DB2 和 CICS 数据的恢复。
CICS DB2 附件工具在 CICS 和 DB2 之间创建了一个整体连接。CICS 应用程序使用此连接向 DB2 发出命令和请求。CICS 和DB2 之间的连接可以随时创建或终止,CICS 和DB2 可以独立启动和停止。您可以命名 CICS 连接到的单个 DB2 子系统,或者(如果您有 DB2 版本 7 或更高版本)您可以使用组附加工具让 DB2 选择 DB2 子系统数据共享组的任何活动成员进行连接。您还可以选择 CICS 自动连接和重新连接到 DB2。一个 DB2 系统可以由多个 CICS 系统共享,但每个 CICS 系统一次只能连接到一个 DB2 子系统。
简单来说,可以将 CICS 视为具有到 DB2 的多个连接池。
定义 DB2 表时,它使用页锁定或行锁定来定义。(可以用表锁定来定义,但这种情况很少见)。DB2 数据库引擎将不允许超过一个用户一次更新一页或一行,这取决于锁定级别。
还有读锁来保持表的读一致性。DB2 将这些读锁称为隔离级别。