如何从连接DB2的JDBC连接获取事务信息排查锁超时问题
DB2 10.5 + WebSphere 8.5 锁超时定位实操方案
1 编程获取JDBC连接对应DB2事务标识信息
你可以通过两种方式获取当前JDBC连接对应的Agent ID、事务ID等标识,用于和你采集到的锁信息做匹配:
- 方式1:基于DB2原生JDBC驱动接口获取(WebSphere 8.5自带的jcc4驱动默认支持)
import java.sql.Connection; import com.ibm.db2.jcc.DB2Connection; // 从WebSphere数据源获取JDBC连接 Connection conn = dataSource.getConnection(); // 先做兼容性判断 if (conn.isWrapperFor(DB2Connection.class)) { DB2Connection db2Conn = conn.unwrap(DB2Connection.class); // 获取当前连接对应的Agent ID,和锁信息中的Agent ID完全匹配 long agentId = db2Conn.getDB2AgentID(); // 可选:获取当前连接的事务ID String transactionId = db2Conn.getTransactionID(); // 建议将agentId和当前请求的链路ID、线程号、业务标识一起输出到应用日志 }
- 方式2:通用SQL查询获取,不依赖驱动私有接口
直接在当前JDBC连接上执行以下查询即可拿到对应标识,兼容性更强:
SELECT AGENT_ID AS agent_id, CURRENT_TRANSACTION_ID AS transaction_id FROM SYSIBMADM.APPLICATIONS WHERE APPLICATION_HANDLE = MON_GET_APPLICATION_HANDLE()
2 关联锁信息获取SQL、绑定参数
首先先开启DB2实例的监控配置(无需重启实例,即时生效):
UPDATE DBM CFG USING DFT_MON_STMT ON DFT_MON_LOCK ON DFT_MON_TABLE ON IMMEDIATE
2.1 确认被锁定的表名
根据你采集到的锁信息中obj={4;511}参数,执行以下查询获取被锁的表:
SELECT TABSCHEMA, TABNAME FROM SYSCAT.TABLES WHERE TBSPACEID = 4 AND TABLEID = 511
2.2 查询持有锁/等待锁的SQL语句
将锁信息中对应的Agent ID填入查询条件即可:
SELECT STMT_TEXT AS sql_text, APPL_ID AS application_id, LAST_EXEC_TIME AS exec_time FROM SYSIBMADM.LONG_RUNNING_SQL WHERE AGENT_ID = ? -- 填入持有锁的Agent ID 295623 或等待锁的Agent ID 28648
2.3 查询SQL对应的绑定参数
锁超时发生后尽快执行以下查询,可获取最近执行SQL的绑定参数值:
SELECT P.STMT_TEXT AS sql_text, D.SEQ_NO AS param_index, D.DATA_VALUE AS param_value, D.PARAM_TYPE AS param_type FROM TABLE(MON_GET_PKG_CACHE_STMT(NULL, NULL, NULL, -2)) P JOIN TABLE(MON_GET_PKG_CACHE_STMT_DETAILS(P.EXECUTABLE_ID, -2)) D ON P.EXECUTABLE_ID = D.EXECUTABLE_ID WHERE P.AGENT_ID = ? -- 填入目标Agent ID ORDER BY P.LAST_EXEC_TIME DESC, D.SEQ_NO ASC
3 多服务器多节点部署适配方案
你可以将获取Agent ID的逻辑嵌入以下位置,方便后续快速定位问题:
- 接入JDBC拦截器:在SQL执行前后统一打印当前连接的Agent ID、请求链路ID、执行SQL和参数
- 接入WebSphere自定义JDBC提供程序拦截器:所有从数据源拿到的连接都自动输出Agent ID和应用节点标识、线程号到日志
锁超时发生后,直接拿锁信息中的Agent ID搜索所有节点的应用日志,即可快速定位到对应的业务请求和代码位置。
内容的提问来源于stack exchange,提问作者João Pedro Schmitt
相关产品推荐
相关产品推荐

