并发编程
您可以设计应用程序来保护访问数据的完整性,同时不会阻止其他进程长时间访问相同数据。
关于本任务
Db2 控制并发的一个基本方法是使用工作单元的锁。 当一个工作单元完成后,该工作单元隐式获取的所有锁都会释放,从而允许新的工作单元开始。 程序中一个工作单元的处理时间会影响 Db2 阻止其他用户访问该锁定数据的时间长度。 当多个程序试图同时使用相同的数据时,每个程序的工作单元应尽可能短,以减少程序之间的干扰。
过程
设计并发应用程序:
- 程序应用以相同的顺序访问数据。当两个应用程序以相同的顺序访问同一张表中的同一行时,其中一个应用程序可能需要等待另一个,但它们不会发生死锁。 因此,建议尝试编写不同的应用程序,以相同的顺序访问行和表。
- 在可行的情况下尽快提交工作,以避免不必要的锁定争用,即使在只读应用程序中也是如此。
在长期运行的恢复单元(UR)中频繁地采取承诺点有以下好处,但代价是CPU使用量和日志写入I/O可能会增加:
- 减少锁争用,特别是在数据共享环境中
- 提高避免锁定的有效性,特别是在数据共享环境中
- 缩短系统故障后 Db2 系统重启的等待时间
- 减少应用程序故障或应用程序发出显式回滚请求后,恢复单元回滚所花费的时间
- 为在线REORG等实用程序提供了更多机会
请考虑使用URCHKTH子系统参数或URLGWTH子系统参数来识别不经常提交的应用程序。 URCHKTH可以识别出在没有UR发布提交的情况下,检查点出现的次数过多。 它有助于监控整个系统的活动。 URLGWTH能够检测出在提交点之间写入过多日志记录的应用程序,这可能会导致关键表出现长时间的恢复情况。
尽管应用程序可能符合正常操作条件下安装的提交频率标准,但系统工作负载波动可能会导致出现变化。 例如,低优先级的应用程序可能会在负载较轻的系统上频繁提交。 然而,在系统负载过重的情况下,应用程序对CPU的使用可能会被抢占,从而导致应用程序违反URCHKTH子系统参数所设定的规则。 因此,请在应用程序中添加逻辑,根据自上次提交以来的时间间隔提交,而不是仅根据执行的 SQL 处理量提交。 此外,在长期运行的只读单元中频繁提交点,以减少锁定争用,并为在线REORG等实用程序提供访问数据的机会。
对于未记录和已记录的对象,频繁提交同样重要。 例如,即使工作是在使用“未登录”选项定义的桌面空间上完成的,也要确保经常提交工作。 即使某项事务仅修改了未登录表空间中的表,在执行更新之前,仍会建立一个恢复单元。 撤销处理将继续向后读取日志,寻找必须应用的撤销日志记录,直到检测到日志中记录的恢复单元的开头。 因此,此类事务应频繁提交,以限制日志中撤销处理可能需要回溯的距离,从而找到恢复单元的开始。
- 在应用程序中加入逻辑,以便在死锁或超时后重试,在没有帮助的情况下尝试从争用情况中恢复。这种方法可以帮助您在没有操作人员协助的情况下从困境中恢复过来。 您可以使用以下方法来确定是否发生超时或死锁:
- SQLCA中的SQLERRD(3)字段
- 诊断报告
- 将大多数应用程序与ISOLATION(CS)和CURRENTDATA(NO)选项绑定。这些选项使 Db2 能够在许多情况下提前解锁,避免取锁。ISOLATION(CS)通常可使 Db2 尽快释放已获取的锁。 CURRENTDATA(NO)通常可使 Db2 获取最少的锁,从而更好地避开锁。当您使用ISOLATION(CS)和CURRENTDATA(NO)时,请考虑将SKIPUNCI子系统的参数值设为YES,这样读取器就不会等待未提交插入的结果。
- 如果您不使用ISOLATION(CS)和CURRENTDATA(NO),请按优先级从高到低顺序使用以下绑定选项:
- ISOLATION(CS)与CURRENTDATA(YES),当返回到应用程序的数据在下次FETCH操作之前不能更改时。
- 隔离(RS),当数据返回到应用程序时,在应用程序提交或回滚之前,不得更改数据。 但是,您并不关心其他应用程序是否插入额外的行。
- 隔离(RR),当查询结果数据在应用程序提交或回滚之前不能更改时。 新的行不能插入到答案集中。
- 请谨慎使用ISOLATION(UR)选项。资源回收服务附件设施 UR 隔离几乎不会对行或页加锁。 它速度快,很少引起争议,但读取的数据不完整。 除非您确定您的应用程序和最终用户能够接受可能出现的逻辑不一致,否则请不要使用它。
如果忽略数据比读取应用程序中未提交的数据更可取,则可以考虑使用“跳过锁定数据”子句。
- 使用序列对象生成唯一的序列号。使用身份列是生成唯一序列号的一种方法。
然而,作为表的一列,身份列与表相关联,并且表只能有一个身份列。 您的应用程序可能需要为多个表使用一组唯一的数字,或者为每个表使用多个数字序列。 作为用户定义的对象,序列为应用程序提供了一种方法,让 Db2 生成唯一的数字键值,并协调多行和多表的键。
使用序列可以避免应用程序实现自己的序列时可能出现的锁争用问题,例如在一行表中包含一个序列号,每个事务都必须递增该序列号。 通过 Db2 序列,许多用户可以同时访问和递增序列,无需等待。 Db2 不会等到一个事务将序列递增后再允许另一个事务再次递增序列。
- 检查多行操作,例如多行插入、定位更新和定位删除,这些操作可能会扩大工作单元。这种情况可能会影响其他用户访问数据的并发性。 您可以通过调整宿主变量数组的大小、在插入、更新之间提交以及防止锁定升级来减少争用。
- 使用全局事务,使 Db2 和其他事务管理器能够参与单个事务,从而共享相同的锁并访问相同的数据。资源回收服务附属设施 (RRSAF) 依赖于一个名为资源回收服务 (RRS) 的组件。 z/OS® 资源回收服务(RRS)。 RRS 提供全系统服务,以协调各产品的两阶段承诺操作。 z/OS 产品。 对于在 RRS 下运行的 RRSAF 应用程序和 IMS 事务,可以将多个 Db2 代理组合成一个全局事务。
全球交易允许多个 Db2 代理商参与同一笔全球交易,从而共享相同的锁和访问相同的数据。 当两个参与全球交易的代理在一个工作单元中访问同一个 Db2 对象时,它们之间不会发生死锁或超时。 下列限制适用:
- 全球交易不支持并行Sysplex®。
- 因为全球交易的每个“分支”共享锁,所以交易的一个分支发布的未提交更新对交易的其他分支可见。
- 跨全球事务分支不支持声明/清空处理,这意味着,如果从同一全球事务的不同分支发出CREATE、DROP、ALTER、GRANT或REVOKE请求,可能会出现死锁或超时。
- LOCK TABLE可能会导致全局事务的分支死锁或超时。
- 使用乐观并发控制。乐观并发控制是一种更快、更具扩展性的锁定替代方案,用于在数据库锁定的情况下进行并发数据访问。 它最大限度地减少了特定资源因其他事务而无法使用的时间。
当应用程序使用乐观并发控制时,会在读取操作前立即获取锁,并在读取操作后立即释放锁。 在更新操作前能马上获取更新锁定,并在事务结束前一直持有锁定。 乐观并发控制使用RID和行更改标记来测试自上次读取操作以来数据是否已被其他事务更改。
因为 Db2 可以确定某一行被更改的时间,所以您可以确保数据完整性,同时限制锁定时间。 通过乐观并发控制, Db2 在读取操作后立即释放行或页锁。 Db2 在每次FETCH后,也会释放行锁,只为定位更新或删除操作获取新的行锁,以确保数据完整性。
为了实现乐观并发控制,您必须使用CREATE TABLE语句或ALTER TABLE语句创建一个行更改时间戳列。 列必须使用以下空特性之一进行定义:
- 在更新时,对于每一行,始终生成一个非空值,作为行更改时间戳
- 更新时,每一行默认不产生,作为行更改时间戳
在您创建换行时间戳列后, Db2 将维护该列的内容。 当您想将此更改令牌作为更新条件时,可以在WHERE子句中为该列指定适当的谓词。