小亦平台会持续给大家科普一些运维过程中常见的问题解决案例,运维朋友们可以在常见问题及解决方案专栏查看更多案例
问题概述
-
核心问题: ORACLE XA 交易挂起。
-
主要现象:
-
数据库端 dba_2pc_pending 存在未决的交易
-
CICS端日志报XID重复的错误。
-
CICS或者应用程序报 ORA-1591 错误,无法获取分布式事务锁。
-
select local_tran_id,
global_tran_id,
state,
to_char(failed_time, 'yyyymmdd hh24:mi:ss')
from dba_2pc_pending;
问题分析
XA (eXtended Architecture) 交易是一种分布式事务处理标准。在 Oracle 数据库中,XA 交易使用两阶段提交 (2PC) 协议来确保跨多个资源管理器(如数据库)的事务一致性。交易挂起通常发生在两阶段提交过程中的 PREPARE 阶段之后:
-
PREPARE 状态挂起: 事务协调器(如 CICS)向所有参与资源(如 Oracle 数据库)发出 PREPARE 请求。Oracle 数据库执行必要的操作并将事务状态标记为 PREPARED(在 dba_2pc_pending 视图中显示为 PREPARE),等待协调器的最终指令(COMMIT 或 ROLLBACK)。如果协调器因故障、网络问题或应用程序错误未能发送最终指令,交易将一直停留在 PREPARE 状态。
-
人工干预后的状态: 当 DBA 手动干预(执行 ROLLBACK FORCE 或 COMMIT FORCE)处理挂起的 PREPARE 交易后,交易状态会变为 ROLLBACK FORCED 或 COMMITED FORCED。此时交易本身已结束,但 dba_2pc_pending 视图中的记录尚未清理。
-
影响:
- 阻塞资源: 挂起的 PREPARE 事务会持有相关的锁和资源(如表行、Undo 段),阻塞其他会话对这些资源的访问。
- ORA-1591: 尝试访问被挂起事务锁定的资源时,会报 ORA-01591: lock held by in-doubt distributed transaction 错误。
- XID 冲突: 如果协调器(如 CICS)尝试使用相同的全局事务 ID (XID) 发起新事务,会因数据库中仍存在相同 XID 的挂起记录而报错。
- 视图残留: COMMITED FORCED 或 ROLLBACK FORCED 状态的记录如果不清理,可能导致后续的 XID 冲突。
解决方案
适用场景:当出现上述任意一种症状时,使用下列的处理步骤。
如果出现state为prepare的交易
并且failed_time字段显示的时间为较早以前的记录,说明XA交易未能自动修改,需要在CICS或ORACLE端人工干预。
-
从CICS端PURGE 挂起的交易该操作后,数据库端一般将自动恢复正常。再次检查dba_2pc_pending,结果应该是prepare状态的记录消失。
select local_tran_id,
global_tran_id,
state,
to_char(failed_time, 'yyyymmdd hh24:mi:ss')
from dba_2pc_pending;
-
如果CICS PURGE交易后PENDING交易仍然没有自动修复,则在数据库端继续下列3-5的操作步骤。
-
查看dba_2pc_pending,依然存在状态为prepared的记录
select local_tran_id,
global_tran_id,
state,
to_char(failed_time, 'yyyymmdd hh24:mi:ss')
from dba_2pc_pending;
-
对prepared状态的交易执行rollback force或者commited force,一般选择回退。
Rollback force '&local_tran_id';
例如:
Rollback force ('2.183.44');
再次执行以下查询
select local_tran_id,
global_tran_id,
state,
to_char(failed_time, 'yyyymmdd hh24:mi:ss')
from dba_2pc_pending;
状态会变成rollback forced
5.执行数据库自带的存储过程,对状态为commited force或rollback force的记录进行清理
exec dbms_transaction.purge_lost_db_entry('&LOCAL_TRAN_ID');
例如:
exec dbms_transaction.purge_lost_db_entry('2.183.44');
如果出现state为commited force或者rollback force的交易
并且failed_time字段显示的时间为较早以前的记录,说明XA交易已经在数据库端人工干预,但是未清理dba_2pc_pending视图中的记录,仍有可能造成和CICS XID重复的问题,需要在数据库端及时进行清理,下面为清理过程。
查看dba_2pc_pending,获取local_tran_id字段
select local_tran_id,
global_tran_id,
state,
to_char(failed_time, 'yyyymmdd hh24:mi:ss')
from dba_2pc_pending;
点击即刻前往小亦知识库查看应急预案完整版:www.ces-xiaoyi.com.cn/#/welcome/k…
运维工作中遇到难题?立即提交工单:www.ces-xiaoyi.com.cn/#/workOrder… 小亦平台工程师火速响应,助您快速修复故障!