【问题标题】:Object Lock issue in DB using stored procedure使用存储过程的数据库中的对象锁定问题
【发布时间】:2013-10-07 20:24:54
【问题描述】:

我有一个从文件加载数据然后尝试将记录插入表中的进程。

如果文件太大,加载 XYZ 表中的所有数据需要一段时间。我正在使用批处理在表中插入记录。

与此同时,另一个进程启动并尝试根据某些条件从 XYZ 表中读取数据,因为第一个进程尚未完成将数据写入表而第二个进程尝试读取相同的数据,我得到一个 Object in use 错误。

我正在考虑两种解决此问题的方法:

  1. 除非所有的记录都是process1插入的,否则status列要保持不同,这样process2就取不到记录了

  2. 以块的形式插入数据,如果出现问题,有一种机制从最后插入的记录重试(需要一种机制)。

我正在使用 DB2 和普通 jdbc 来插入记录。

请让我知道解决此问题的最佳方法是什么

【问题讨论】:

  • 另一种选择是在一个事务中执行所有插入操作,这样其他人在您的加载过程完成之前不会看到这些插入操作。顺便说一句:您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • 我正在使用 DB2,我正在使用普通 jdbc 在 DB 中插入记录

标签: java jdbc db2 prepared-statement ibm-midrange


【解决方案1】:

V4.5 是一个古董,但即使在那个时候,大多数正常的数据库操作都不需要对文件进行排他锁。听到这里涉及到对象锁,我感到非常惊讶。

我建议稍微修改一下 IBM 方面。像现在一样继续使用 JDBC 将行加载到 DB2 表中,但是当批量加载完成后,将一行加载到新表中。新表中的这一行将触发 IBM 进程去处理完全加载的原始表。 IBM 管理员可以使用新表上的触发器来获得新记录到达的通知。

如果无法修改 IBM 端,请考虑加载临时表,然后使用JT400 发出 CPYF 命令让 IBM OS 将行复制到真实表中。这应该比通过网络运行得快得多。或者,将其从 TEMPFILE 重命名为 REALFILE,但 IBM 进程可能不喜欢这样。

【讨论】:

  • 我编写了一个示例程序来证明 DB Operations 获得了文件的排他锁。我不可能修改 IBM 端。我正在考虑在表中再引入一列,并在表中插入所有行后填充一些值,例如“N”并将该值更新为 Y。另一个进程将只选择新列中数据为“Y”的行。它应该以这种方式工作。您如何看待这种方法?
  • 我们可能有术语问题。在 OS/400 上,独占锁意味着系统上没有其他进程甚至可以查看您的表。您可以通过 OS400 命令 WRKOBJLCK 判断您拥有什么锁。如果不能修改IBM端,如何允许添加列?
  • 请原谅我的误解。是的,如果需要,我可以修改表格。
  • 我看不到新列如何解决引发“正在使用的对象”错误的第二个进程。
  • 第二个进程不会选择第一个进程同时插入的那些行,因此它可以避免 File in Use 错误
【解决方案2】:

您没有说您正在使用什么数据库或库,但您应该考虑使用事务来控制同时读取和写入。进程 1 应该在单个事务中写入数据块。在全部写入之前,这些数据对进程 2 是不可见的,因此您不应该在两者之间产生任何冲突。这是假设您在数据上设置了正确的事务隔离级别。

例如,如果您使用的是 Spring,那么很容易使用 @Transactional 标记函数,以便 tat 函数中的所有 DB 调用都在单个事务中运行。

【讨论】:

  • 我正在使用一个事务来插入所有内容,因为数据太大,它以某种方式最终锁定了整个文件,即表,因此当下一个计划进程运行时,它无法检索任何内容那个表,bcz系统说文件正在使用中。
  • @Abs:您是说插入次数过多会导致 DB2 中的表锁定吗?这很蹩脚。那是哪个 DB2 版本?我认为在较新的版本中,读者永远不会被作者屏蔽。
  • 我使用的是 Db2 iseries v4.5。
  • 您插入的记录百分比是多少?每个进程使用什么隔离级别?两个进程都引用物理文件(表),还是涉及逻辑文件或索引?
  • @WarrenT:我正在插入 100,000 条记录。隔离级别为已提交读。这两个进程都引用了物理文件。
猜你喜欢
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
相关资源
最近更新 更多