首页 > 解决方案 > 如何从 JDBC 连接到 DB2 数据库获取事务信息?

问题描述

我面临一些锁定超时问题,我需要更好的工具来找到根本原因。考虑 IBM 堆栈、WebSphere 8.5 和 DB2 10.5,并给出如下锁信息:

Lock Information:

   Lock Name:      000301230000000008C0000252
   Lock Type:      Basic RECORD lock(DMS/IXM)
   Lock Specifics: (obj={4;511}, rid=d(0;2440;6), x0000000002A00001)

Lock Requestor:
   ...
   Requesting Agent ID:     28648
   Coordinator Agent ID:    28648
   ...

Lock Owner (Representative):
   ...
   Requesting Agent ID:     295623
   Coordinator Agent ID:    295623
   ...

并且假设我有两个 JDBC 事务,一个持有锁,另一个等待释放锁,我如何以编程方式从 JDBC 连接(例如代理 ID)获取事务信息,以在我的应用程序中诊断 JDBC 连接的哪个实例拿着锁?假设我有一个多线程、多服务器的环境。

我在这个链接上看到了一个关于 Oracle、SQLServer 和 PostgreSQL 的类似问题:How to get the current database transaction id using JDBC or Hibernate? 但是我没有找到任何关于 DB2 的信息

要解决锁定原因,我需要找到:

标签: javajdbcdb2websphere

解决方案


SYSIBMADM.MON_LOCKWAITS视图开始。

如果您需要有关参与应用程序的更多信息,您可以使用此视图直接基于的监控表函数:
MON_GET_APPL_LOCKWAIT
MON_GET_CONNECTION

SELECT 
  -- locked table
  CASE WHEN L.TBSP_ID > 0 THEN T.TABSCHEMA ELSE S.TABSCHEMA END AS TABSCHEMA
, CASE WHEN L.TBSP_ID > 0 THEN T.TABNAME   ELSE S.TABNAME   END AS TABNAME
, CASE WHEN L.TBSP_ID > 0 THEN T.DATA_PARTITION_ID ELSE -1  END AS DATA_PARTITION_ID
--, L.* -- lock info 
, H.CLIENT_HOSTNAME -- holder connection info 
, HC.STMT_TEXT AS HLD_STMT_TEXT_CURR -- holder's currently executing statement
, HL.STMT_TEXT AS HLD_STMT_TEXT_LAST -- holder's last executed statement
, R.CLIENT_HOSTNAME -- requester connection info  
, RC.STMT_TEXT AS REQ_STMT_TEXT_CURR -- requester's current statement
FROM TABLE (MON_GET_APPL_LOCKWAIT (NULL, -2)) L
LEFT JOIN TABLE (MON_GET_TABLE (NULL, NULL, L.HLD_MEMBER)) T ON T.TBSP_ID = L.TBSP_ID AND T.TAB_FILE_ID = L.TAB_FILE_ID 
LEFT JOIN SYSCAT.TABLES S ON S.TBSPACEID = L.TBSP_ID AND S.TABLEID = L.TAB_FILE_ID 
-- Holder's info
LEFT JOIN TABLE (MON_GET_CONNECTION (L.HLD_APPLICATION_HANDLE, L.HLD_MEMBER)) H ON 1=1
LEFT JOIN TABLE (MON_GET_ACTIVITY (L.HLD_APPLICATION_HANDLE, L.HLD_MEMBER)) HC ON 1=1
LEFT JOIN TABLE (MON_GET_UNIT_OF_WORK (L.HLD_APPLICATION_HANDLE, L.HLD_MEMBER)) HU ON 1=1
LEFT JOIN TABLE (MON_GET_PKG_CACHE_STMT (NULL, HU.LAST_EXECUTABLE_ID, NULL, L.HLD_MEMBER)) HL ON 1=1
-- Requester's info
LEFT JOIN TABLE (MON_GET_CONNECTION (L.REQ_APPLICATION_HANDLE, L.REQ_MEMBER)) R ON 1=1
LEFT JOIN TABLE (MON_GET_PKG_CACHE_STMT (NULL, L.REQ_EXECUTABLE_ID, NULL, L.REQ_MEMBER)) RC ON 1=1

笔记:

  • 您无法获得放置锁的语句,请求者正在等待。锁与将该锁放置在 Db2 中的语句之间没有显式绑定。您可能会获得上述持有人的当前声明(如果有)和最后完成的声明。这些语句都不能放置这个锁。
  • 您无法使用上述查询获取所有返回语句的参数值。

要获得有关锁定等待/超时事件的更多信息,您可以做的是创建一个用于锁定的事件监视器- 某种用于锁定等待、锁定超时、死锁事件的“记录器”。相应的信息将写入为此监视器创建的数据库表中。请参阅写入表的信息以了解锁定事件监视器主题。您在这些表中获得的数据量取决于数据库配置参数的设置:

锁定超时事件 ( MON_LOCKTIMEOUT ) = HIST_AND_VALUES
死锁事件 ( MON_DEADLOCK ) = HIST_AND_VALUES
锁定等待事件 ( MON_LOCKWAIT ) = HIST_AND_VALUES
锁定等待事件阈值 ( MON_LW_THRESH ) = 5000000

例如,如果您如上设置这些参数,则所有 3 类事件(如果请求者等待超过 5 秒,将生成 lockwait 事件)的非常详细的信息(包括所有语句参数值)将写入事件监视器表。
如果您有这样一个活动的事件监视器,并且MON_DEADLOCK = HISTORY至少,对于当前db2pd -apinfo -db mydb在服务器上运行的所有打开事务的应用程序,您对整个事务历史记录有一个额外的活动。


推荐阅读