这是检查Postgres是否已提交交易ID

时间:2017-07-04 09:38:00

标签: java database postgresql transactions ipc

在Postgresql中,如果交易ID为" 123456",则表名为" table1"那我是否正确执行以下查询? :

Select count (*) from table1 where xmin=123456 OR xmax=123456

如果count返回值> 1,那么我可以假设事务ID被提交了吗?

_

注意:

  1. 事务ID从不同的java程序发送到另一个java 程序通过RMI(或)TCP套接字(或)文件(或)其他一些机制
  2. 从更新,插入,删除后收集交易ID 触发
  3. 在这些操作过程中不执行真空或任何其他维护程序
  4. 不要担心txid环绕问题
  5. 当使用oracle时,v $ transaction来救援...... 但是在Postgres,我找不到类似的东西...... 虽然一些谷歌搜索让我相信有办法找到它使用" pg_log"文件或" pg_locks"查看,但我无法弄清楚如何

    我唯一能想到的就是 xmin和xmax ......我甚至无法判断它是否是一种肮脏的方法

    是否有任何Postgresql Sensei可以带领我朝着正确的方向前进?

    更新

    对于postgresql 9.5及更高版本," laurenz albe"的答案是完美的...... 对于那些使用Postgresql 9.0到9.3的人,你应该使用

    SELECT count(xmin) as SIZE FROM table1 WHERE xmin = 123456 AND xmax = 0
    

    此外,当发生删除操作并且您获得了交易ID时,我们需要以不同的方式检查它......

    SELECT count(xmin) as SIZE FROM table1 WHERE xmin = 123456 OR xmax = 123456
    

    然后检查结果。如果它返回零,则提交删除操作...如果结果非零,则回滚事务,您不必担心未提交的事务

    注意: 这是为了检查从触发器接收并发送到另一个外部程序(java)的事务id是否已提交但未回滚且数据库会话是否不同......

2 个答案:

答案 0 :(得分:1)

如果您看到xmin=123456txid_current() <> 123456是 - 则会提交 123456 交易。

在postgres中没有transactionId这样的列。

答案 1 :(得分:1)

xmax的测试错误。

当行版本(PostgreSQL中的元组)被xmaxUPDATE标记为无效时,

DELETE会被设置。这意味着没有具有后续事务ID的事务可以看到此元组,并且只要没有人能够再看到它就可以回收它。

如果回滚事务,则不会重置xmax的值 - 事务状态存储在提交日志中,并且元组仍然对其他人可见。

xmax也用于存储行锁。

因此,如果您可以看到xmax = '123456'所在的元组,则表示以下其中一项:

  • 元组已删除或更新且事务已提交,但您的事务快照较旧,因此您仍然可以看到旧元组。

  • 删除或更新了元组,并回滚了事务。

  • 元组被交易123456锁定,例如使用SELECT ... FOR UPDATE

另一方面,如果您看到一个带有xmin = '123456'的元组并且这不是您当前的事务,您可以确定此事务已提交。

所以你的测试应该是

SELECT count(*) FROM table1 WHERE xmin='123456';

但这是一个可怕的查询。它强制对整个表进行顺序扫描,不允许对系统列进行索引。

如果您使用的是PostgreSQL 9.5或更高版本,请考虑激活track_commit_timestamp并使用函数pg_xact_commit_timestamp(xid)。对于未提交的事务,它将返回NULL。