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

时间:2014-08-01 09:57:18

标签: postgresql

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

我可以通过某种方式组合这两个语句来实现吗?

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

-- rollback transaction by identifier
ROLLBACK PREPARED 'GID';

2 个答案:

答案 0 :(得分:3)

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

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

我只建议在不关心数据的调试/测试系统上执行此操作。否则,在验证它们不重要后,手动回滚单个事务。 2PC通常在数据很重要时使用,而PREPARE TRANSACTION相当于实际COMMIT,就大多数应用而言 - 他们希望提交实际上会到达磁盘。当然,在这种情况下你不应该丢失准备好的xacts,因为你的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,))

答案 1 :(得分:2)

正是在这种情况下,我没有选择(轻松)使用@Craig Ringer上面的答案中的优秀Python脚本,但是在我的系统上设置了Groovy - 这里&#39 ;在Groovy中也是如此,以防万一它可以用于其他任何人:

Filters