首页 > 解决方案 > DB2 iSeries 不锁定选择更新

问题描述

我正在使用 AS400 上的 DB2 iSeries 迁移遗留应用程序,该应用程序具有我必须使用 .NET 和用于 .NET 的 DB2.Data.DB2.iSeries 客户端重现的特定行为。我所描述的内容适用于 DB2 非 AS400,但在 AS400 DB2 中,它适用于我要替换的遗留应用程序 - 但不适用于我的应用程序。

原始应用程序中的行为:

  1. 开始交易
  2. ExecuteReader () => select col1 from table1 where col1 = 1 for update。
  3. 该行现在已锁定。尝试运行 Select for update 的任何其他人都应该失败。
  4. 关闭在第 2 行打开的阅读器。
  5. 该行现已解锁。- 任何尝试运行 select for update 的人都应该成功。
  6. 完成交易,从此过上幸福的生活。

在我的 .NET 代码中,我有两个问题:

  1. 第 2 步 - 仅检查该行是否已被锁定 - 但实际上并未锁定它。所以另一个用户可以并且确实运行 select for update - 错误行为

  2. 一旦可行 - 我需要在阅读器关闭时解锁锁(步骤 4)

这是我的代码:

var cb = new IBM.Data.DB2.iSeries.iDB2ConnectionStringBuilder();
cb.DataSource = "10.0.0.1";
cb.UserID = "User";
cb.Password = "Password";
using (var con = new IBM.Data.DB2.iSeries.iDB2Connection(cb.ToString()))
{

    con.Open();
    var t = con.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
    using (var c = con.CreateCommand())
    {
        c.Transaction = t;
        c.CommandText = "select col1 from table1 where col1=1 FOR UPDATE";
        using (var r = c.ExecuteReader())
        {
            while (r.Read()) {
                MessageBox.Show(con.JobName +  "The Row Should Be Locked");
            }
        }
        MessageBox.Show(con.JobName +  "The Row Should Be unlocked");
    }
}

当您运行此代码两次时 - 您会看到两个进程都到达“该行应该被锁定”,这就是我所描述的问题。

期望的结果是第一个进程将到达“应锁定此行”,而第二个进程将因资源繁忙错误而失败。

然后,当第一个进程到达第二个消息框 - “该行应该被解锁”时,第二个进程(再次运行后)将到达“该行应该被锁定”消息。

任何帮助将不胜感激

标签: db2-400

解决方案


文档说:

使用 UPDATE 子句时,引用游标的 FETCH 操作获取排他行锁。

这意味着正在使用游标,并且在执行 fetch 语句时发生锁定。我在您的代码中没有看到游标或提取。

现在,我不知道 .NET 是否将其作为游标处理,但 DB2 UDB 文档没有这种表示法。


推荐阅读