【问题标题】:How can I determine if my COBOL program which uses DB2 CICS will cause deadlocks for other transactions?如何确定使用 DB2 CICS 的 COBOL 程序是否会导致其他事务死锁?
【发布时间】:2014-12-09 23:14:26
【问题描述】:

我目前正在开发一个使用 COBOL 连接到 DB2 的系统。示例浏览将由以下语句启动:

       EXEC SQL
         DECLARE <cursor name> CURSOR FOR
         SELECT
             <field names>
         FROM <table name>
         WHERE
             <conditions>
         ORDER BY
             <key fields>
         FOR FETCH ONLY
         OPTIMIZE FOR 1 ROW
       END-EXEC.

       EXEC SQL
            OPEN <cursor name>
       END-EXEC.

一旦确定浏览成功,将使用以下命令对表进行后续读取:

       EXEC SQL
         FETCH <cursor name>
         INTO
             <variable names>
       END-EXEC.

例如,如果我正在浏览一个表并且返回的结果集大约有 100,000 行,则需要数小时来处理。如果我可以确保系统的其他用户在我正在浏览的同一个表上进行处理时不会遇到死锁 (-911),那就没问题了(处理意味着选择、更新和可能删除记录)。

如何确定我正在执行的浏览操作是否可能导致其他用户死锁?

(注意:我没有做任何更新,只是纯粹检索数据)

【问题讨论】:

  • 您在大型机上运行。为什么你会认为处理它需要“几个小时”?在测试数据库上尝试。与您的同事交谈。询问您的 DBA。在可能出现死锁的情况下,他们会知道您应该如何处理它,并且他们可以更好地展示可能没有死锁的地方。
  • 在 CICS 中,100,000 行是否要在一个事务中处理?一旦开始超过几秒钟,我会担心这会被标记为长时间运行的事务。在这些情况下仍会发生锁升级。从表面上看,对于 UR 甚至 CS,您更有可能成为受害者。如果这是一项架构任务,是否可以从间隔控制分批完成?还是从批次?是否有可以在 Query 中执行的逻辑?分页?

标签: sql db2 deadlock cobol cics


【解决方案1】:

一个帮助发现潜在死锁问题的工具是 EXPLAIN 的输出。与您的 DBA 交谈。

您说您的结果集可能是 100,000 行。不要那样做。没有用户会滚动那么多行。添加其他选择条件以允许他们过滤结果集。

您不会对结果集保持锁定。我见过的一种技术是只检索足够的数据以供用户进行选择,然后在做出选择时检索其余的数据。

【讨论】:

  • 我认为提问者使用的是 CICS 意义上的“浏览”——如在 STARTBRowse、处理数据集、ENDBRowse 中——而不是在用户浏览中。这听起来像是后台处理,与屏幕无关。
【解决方案2】:

在大型机环境中,性能就是一切!并不是因为大型机速度很快,我们就可以忽略性能要求。

在在线程序中我推荐使用

FETCH FIRST N ROWS ONLY 

其中用户页面大小为 N-1。如果您成功获取光标中的 N 行,则会有更多页面,并且您会以某种方式通知您的用户。

在您的 DB2 查询中;

如果您在进行 BATCH 处理,最好使用 DB2 实用程序或 DFSORT/ICETOOL/SYNCSORT 卸载数据,并使用适当的 DD SORTDBIN 传递您的 SQL 查询。

【讨论】:

  • 不完全是“全部”,但肯定比不存在数据量和直接处理成本(cpu/io 收费)更重要。我最初错过了CICS 标签。如果它是 CICS 程序中某种类型的“求和”过程,那么求和应该在 CICS 之外完成,这样该值就可以方便地使用。单个 CICS 事务的 100,000 次数据库访问并不好。您的第一个赞。
  • 哦,SORTDBIN 是一个 SyncSORT-only 的东西。
  • 不将数据从数据库中取出来处理它有点违背拥有数据库的目的吗?
  • @JoeZitzelberger 绝不是。事后回溯。尽管 DB 命令语言可以完成所有需要完成的工作,但有时如果不使用资源(包括时间)就无法完成。如果卸载/操作/重新加载给出相同的结果,但速度更快......这是一种常见的大型机方式。无论如何,我不确定这个问题是否很好。
【解决方案3】:

如果您只是进行浏览操作,“FOR FETCH ONLY”(又名 FOR READ ONLY)子句非常有用。如果包绑定上设置的隔离级别允许,您可能还想查看“SKIP LOCKED DATA”子句和“WITH UR”(未提交读取)的隔离级别。

所有这些都假设您的业务规则将允许您仅处理其他进程目前未使用的脏行。

如果在完成所有这些操作后,您仍然看到死锁,您可能会考虑将您的 curson 转换为已声明的临时表并以这种方式进行处理。这将保证您的数据没有其他读取器或写入器,但会以额外的 DASD 和核心资源为代价。

【讨论】:

    【解决方案4】:

    如果表包含 100,000 行,您很可能会“过滤” FETCH 以选择进行展示。如果可能的话,在 SQL SELECT 中包含“过滤”信息。您的 DBA 看到的事务统计信息将确定额外的 INDEX BY 语句是否会使事务运行得更好。

    【讨论】:

      猜你喜欢
      • 2012-05-02
      • 2021-02-08
      • 2021-11-08
      • 2014-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      相关资源
      最近更新 更多