Java 这是检查Postgres是否提交了事务id的正确方法吗

Java 这是检查Postgres是否提交了事务id的正确方法吗,java,database,postgresql,transactions,ipc,Java,Database,Postgresql,Transactions,Ipc,在Postgresql中,如果事务id为“123456”,表名为“table1”,那么我执行以下查询是否正确 Select count (*) from table1 where xmin=123456 OR xmax=123456 如果count返回值>1,那么我可以假设事务id已提交吗 _ 注意: 事务id从不同的java程序发送到另一个java程序 通过RMI(或)TCP套接字(或)文件(或)某种其他机制进行编程 事务id是在更新、插入、删除后从 触发 这些操作期间不执行真空或任何其他维

在Postgresql中,如果事务id为“123456”,表名为“table1”,那么我执行以下查询是否正确

Select count (*) from table1 where xmin=123456 OR xmax=123456
如果count返回值>1,那么我可以假设事务id已提交吗

_

注意:

  • 事务id从不同的java程序发送到另一个java程序 通过RMI(或)TCP套接字(或)文件(或)某种其他机制进行编程
  • 事务id是在更新、插入、删除后从 触发
  • 这些操作期间不执行真空或任何其他维护程序
  • 也不要担心txid封装问题
  • 使用oracle时,v$交易起到了解救作用…但在Postgres中,我找不到类似的交易。。。 虽然一些谷歌搜索让我相信有办法通过“pg_log”文件或“pg_locks”视图找到它,但我不知道如何找到它

    我能想到的唯一肮脏的方式是xmin和xmax。。。我甚至不知道这是不是一个肮脏的方法

    有没有什么Postgresql的老师能带领我走向正确的方向

    更新:

    对于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是否已提交且未回滚,以及数据库会话是否不同……

    如果看到
    xmin=123456
    txid\u current()123456
    是,则提交事务123456


    postgres中没有
    transactionId
    这样的列。

    xmax
    的测试是错误的

    xmax
    在行版本(PostgreSQL中的元组)被
    UPDATE
    DELETE
    标记为无效时设置。这意味着没有一个具有更晚事务ID的事务可以看到这个元组,并且只要没有人可以看到它,它就可以被回收

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

    但是
    xmax
    也用于存储行锁

    因此,如果您可以看到一个元组,其中
    xmax='123456'
    ,它表示以下之一:

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

    • 元组被删除或更新,事务被回滚

    • 该元组被事务123456锁定,例如使用
      SELECT。。。用于更新

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

    所以你的测试应该是

    SELECT count(*) FROM table1 WHERE xmin='123456';
    
    但这是一个非常糟糕的问题。它强制对整个表进行顺序扫描,不允许对系统列进行索引


    如果您使用PostgreSQL 9.5或更新,请考虑激活和使用该函数。对于未提交的事务,它将返回NULL。

    所以您只想知道表1中是否存在transactionId为123456的行?为什么不从transactionId='123456'所在的表1中选择count(*?@DaveH我不知道有一个名为
    transactionId
    的系统列,它在postgres 9.0和9.3中是否有效?请不要为这个问题添加可能的解决方案。问题应该只包含问题本身的一部分信息。@realpoint,对不起。。。已删除…@DaveH,您确定有一个名为
    transactionId
    的系统列吗?因为当我检查时,我找不到它…这是正确的方法吗?。。。还是有其他微妙的方式?或者任何有效的方法?如果是这样的话,我会把这个标记为正确答案。。。请确认……事实上我已经忘记了
    v$transaction
    ,因为我已经多年没有使用Oracle了。我想不起在博士后有什么相似之处。要获得pg_锁,您必须锁定关系,
    transactionid
    不一定会被填充。所以我想说你的方法看起来很合理,这是不正确的。如果您看到
    xmax
    ,这并不意味着事务已提交。@CrystalPaladin请查看Laurenz Albe答案-我希望您接受他的答案,而不是minepostgresql 9.5?我左右为难。。。我正在寻找解决方案9.0到9.3。。。我会将此标记为答案,但这并不能解决我的问题…还有其他解决方案吗?如果没有,我将求助于你提到的
    糟糕的
    查询。。。但至少我会有一个解决办法。。。总比什么都没有好…我在回答的最后一段提供了另一种解决方案。感谢您的努力。。。我使用Postgresql 9.3,并期望与9.0兼容,这就是为什么我决定将查询与xmin一起使用,而不是
    pg\u xact\u commit\u timestamp(xid)
    ,后者不适用于9.3,更不用说9.0了