控制C时自动解锁表

问题描述 投票:0回答:1

我观察到,如果我在正在运行的 Perl DBI 脚本上按下 Control C,则同一脚本的下一次运行将会挂起。

我用ps确认了点击control C后脚本没有运行。

我正在使用 PerlDBI 和 DB2。

  1. 如何运行查询来查看未完成的锁?
  2. 我如何更改我的代码,以便它将在控制 C 上进行回滚并解锁表。
  3. 如何从 Perl 脚本中释放锁定?
perl dbi db2-luw
1个回答
0
投票

应用程序进程、并发和恢复:

当应用程序进程结束时,数据库管理器会释放它已获取并保留的所有锁。

如果你的应用程序真的结束了,那么它的所有锁都必须被释放(我们在这里不考虑两阶段提交事务 - 在这种情况下事情会更复杂)。
因此,当您按 Ctrl-C 时,可能会发生不同的情况 - 您不会终止客户端连接,或者 DB2 仍然认为该连接处于活动状态(但 DB2 应该自动检测意外的客户端终止并断开应用程序的连接并释放其锁定) ).

您可以使用以下方法来了解不同数据库连接会发生什么情况。
SYSIBMADM.MON_LOCKWAITS 视图显示谁是持有者(

HLD_*
列)和谁是等待者(
REQ_*
列)以及该锁等待的对象是什么表(
TABSCHEMA
TABNAME
)。

MON_GET_LOCKS 表函数显示锁,例如由某个应用程序句柄(会话)持有或放置到某个表的锁。几个例子。

如果您知道应用程序句柄 (XXX):

SELECT F.TABSCHEMA, F.TABNAME, L.LOCK_OBJECT_TYPE, L.LOCK_MODE FROM TABLE (MON_GET_LOCKS('<application_handle>XXX</application_handle>', -2)) L , TABLE ( SELECT MAX (DECODE (NAME, 'TABSCHEMA', VALUE::VARCHAR (128))) AS TABSCHEMA , MAX (DECODE (NAME, 'TABNAME', VALUE::VARCHAR (128))) AS TABNAME FROM TABLE (MON_FORMAT_LOCK_NAME (L.LOCK_NAME)) ) F
如果您知道完整的表名称:

MY_SCHEMA.MY_TABLE

SELECT APPLICATION_HANDLE, LOCK_OBJECT_TYPE, LOCK_MODE FROM TABLE (MON_GET_LOCKS('<table_schema>MY_SCHEMA</table_schema><table_name>MY_TABLE</table_name>', -2))
可以通过使用 ADMIN_CMD 过程的 

FORCE APPLICATION 命令通过其应用程序句柄强制应用程序脱离数据库。例如,如果您看到一些锁等待,您可以获取 SYSIBMADM.MON_LOCKWAITS.HLD_APPLICATION_HANDLE(持有锁的应用程序句柄)中的值(例如 XXX),并在以下调用中使用它来强制其退出数据库:

CALL SYSPROC.ADMIN_CMD('force application (XXX)')

    

© www.soinside.com 2019 - 2024. All rights reserved.