---
title: 通过脚本检查并回滚悬挂 XA 事务-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于通过脚本检查并回滚悬挂 XA 事务相关的常见问题和使用技巧，帮助您快速解决通过脚本检查并回滚悬挂 XA 事务的难题。
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# 通过脚本检查并回滚悬挂 XA 事务

更新时间：2026-06-10 09:51

适用版本： V2.2.x 内容类型：How-to  

本文介绍如何通过脚本检查悬挂 XA 事务，并进行回滚。

## 适用版本

OceanBase 数据库 V2.2.7X 版本

## 检查并回滚悬挂 XA 事务

目前，OceanBase 数据库中，当某个 RM（Resource Manager，资源管理器） 提交异常时，TM（Transaction Manager，事务管理器）未正常发送 Rollback 到 OceanBase 数据库，导致数据库端的 XA 事务一直处于 Prepare 阶段，并最终导致 Clog 无法回收，合并异常。

可以通过在任意一台 OBServer 上运行以下 Python 脚本，完成悬挂 XA 事务的自动巡检。 其中 `interval 480 second`表示回滚超过 8 分钟的事务，`ROUND((sysdate - cast(GMT_MODIFIED as date)) * 86400) > 600` 表示每 5 分钟进行一次巡检。

```unknow
import subprocess
import logging
import time
import os

logging.basicConfig(filename='xa_trans_rollback.log', level=logging.INFO, filemode='a')
rollback_xa_cmd='''
DECLARE
  CURSOR cur
  IS
    SELECT GMT_MODIFIED,
      state,
      rawtohex(GTRID) gtrid,
      rawtohex(BQUAL) bqual,
      FORMAT_ID
    FROM sys.all_virtual_tenant_global_transaction_agent
    WHERE state = 3
    AND ROUND((sysdate - cast(GMT_MODIFIED as date)) * 86400) > 600;
  l_xid DBMS_XA_XID;
  l_ret PLS_INTEGER;
BEGIN
  FOR rec IN cur
  LOOP
    l_xid.formatid := rec.format_id;
    l_xid.gtrid    := hextoraw(rec.gtrid);
    l_xid.bqual    := hextoraw(rec.bqual);
    l_ret          := DBMS_XA.XA_ROLLBACK(xid => l_xid);
    dbms_output.put_line(l_ret);
  END LOOP;
END;
/
'''

while True:
    try:
        cur_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
        pending_trans_cmd = "mysql -hxxx.xx.xxx.xx -Pxxxx -uroot@sys#$cluster -p'$passwd' -c -Doceanbase -e 'select count(*) from __all_virtual_trans_stat where tenant_id=$tenant_id and part_trans_action > 2 and ctx_create_time < date_sub(now(),interval 480 second);'"
        p = subprocess.Popen(pending_trans_cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
        pending_trans_cnt= p.communicate()[0].replace('count(*)','').strip("\n")
        if int(pending_trans_cnt) > 0:
            pending_xa_rollback = "obclient -hxxx.xx.xxx.xx -P3306 -usys@obzy1#$cluster -p'$passwd' -e '" + rollback_xa_cmd + "'"
            os.system(pending_xa_rollback)
            logging.info(cur_time + ': ' + pending_trans_cnt + ' pending trans were rollbacked!')
        else:
            logging.info(cur_time + ":  No pending trans found!")
        time.sleep(300)
    except:
        cur_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
        logging.error(cur_time + ":  Error, get pending trans failed!")
        time.sleep(300)

```

上一篇

[6004 错误码的报错原因和场景](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000267159)

下一篇

[OBServer 日志出现 out of px worker resource 的原因](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000267156) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
