如何回滚所有打开的 PostgreSQL 事务

Ing*_*her 8 postgresql

如何回滚特定数据库的所有打开的 postgres 事务?

我可以通过以某种方式组合这两个语句来做到这一点吗?

-- get transaction identifiers
SELECT gid FROM pg_prepared_xacts WHERE database='mydb';

-- rollback transaction by identifier
ROLLBACK PREPARED 'GID';
Run Code Online (Sandbox Code Playgroud)

Cra*_*ger 4

ROLLBACK PREPARED只影响准备好的两阶段提交事务。对普通交易没有影响。

如果您实际上希望回滚所有准备好的事务,那么您可以通过循环来完成,pg_prepared_xacts如您所示。但是,由于ROLLBACK PREPARED无法在事务中运行,因此您必须从外部客户端应用程序执行此操作。

我只建议在不关心数据的调试/测试系统上执行此操作。否则,在确认单个事务不重要后,手动回滚它们。2PC 通常在数据很重要时使用,对于大多数应用程序而言, aPREPARE TRANSACTION相当于实际的- 他们期望提交实际上会到达磁盘。COMMIT当然,在这种情况下您不应该丢失准备好的 xact,因为您的 XA 事务管理器(或您正在使用的任何东西)应该跟踪并恢复准备好的但未提交的事务。

这是我最近为了这样的目的而编写的一个快速而肮脏的脚本:

#!/usr/bin/env python
#
# Purges all prepared xacts from the specified database
#
# On Windows the easiest way to get psycopg2 is with ActiveState python:
#
# ActivePython (http://www.activestate.com/activepython/downloads)
# psycopg2 (http://code.activestate.com/pypm/psycopg2/)

import sys
import psycopg2
import subprocess

if len(sys.argv) != 2:
    print('Usage: cleanup_prepared_xacts.py "dbname=mydb ..."')

conn = psycopg2.connect(sys.argv[1])
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

curs = conn.cursor()
curs.execute("SELECT gid FROM pg_prepared_xacts WHERE database = current_database()")
for (gid,) in curs.fetchall():
    curs.execute("ROLLBACK PREPARED %s", (gid,))
Run Code Online (Sandbox Code Playgroud)