这是检查 Postgres 是否提交事务 ID 的正确方法吗
Is this a right way to check if Postgres Committed a Transaction id
在Postgresql中,如果事务id是“123456”,table名称是"table1"那么我是否可以执行下面的查询? :
Select count (*) from table1 where xmin=123456 OR xmax=123456
如果计数 returns 值 > 1,那么我可以假设事务 ID 已提交吗?
_
注:
- 交易 ID 从不同的 java 程序发送到另一个 java
通过 RMI (OR) TCP Sockets (OR) File (OR) 一些其他机制编程
- 事务 ID 是从更新、插入、删除之后收集的
触发器
- 在这些操作期间不执行真空或任何其他维护程序
- 也不用担心 txid 环绕问题
当使用 oracle 时,v$transaction 来拯救... 但是在 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
然后查看结果。如果它 returns 为零,则提交删除操作...如果结果为非零,则回滚事务,您无需担心未提交的事务
注:
这是为了检查从触发器接收并发送到另一个外部程序(java)的事务 ID 是否已提交且未回滚并且数据库会话不同...
如果您看到 xmin=123456
并且您的 txid_current() <> 123456
是 - 那么事务 123456 已提交。
postgres 中没有 transactionId
这样的列。
xmax
的测试是错误的。
当行版本(PostgreSQL 中的 元组 )被 UPDATE
或 DELETE
标记为无效时,xmax
被设置。意思是后面的交易ID的交易都看不到这个元组,一旦再也看不到它就可以回收
如果事务被回滚,xmax
的值不会被重置——事务状态存储在提交日志中,并且元组仍然可见其他。
但是xmax
也是用来存储行锁的
因此,如果您可以在 xmax = '123456'
处看到一个元组,则表示以下之一:
元组已删除或更新,事务已提交,但您的事务快照较旧,因此您仍然看到旧元组。
元组被删除或更新,事务被回滚。
元组被事务 123456 锁定,例如SELECT ... FOR UPDATE
.
另一方面,如果您看到带有 xmin = '123456'
的元组并且这不是您当前的事务,您可以确定该事务已提交。
所以你的测试应该是
SELECT count(*) FROM table1 WHERE xmin='123456';
但这是一个 糟糕的 查询。它强制对整个 table 进行顺序扫描,并且不允许在系统列上建立索引。
如果您使用的是 PostgreSQL 9.5 或更新版本,请考虑激活 track_commit_timestamp
and using the function pg_xact_commit_timestamp(xid)
。对于未提交的事务,它将 return NULL。
在Postgresql中,如果事务id是“123456”,table名称是"table1"那么我是否可以执行下面的查询? :
Select count (*) from table1 where xmin=123456 OR xmax=123456
如果计数 returns 值 > 1,那么我可以假设事务 ID 已提交吗?
_
注:
- 交易 ID 从不同的 java 程序发送到另一个 java 通过 RMI (OR) TCP Sockets (OR) File (OR) 一些其他机制编程
- 事务 ID 是从更新、插入、删除之后收集的 触发器
- 在这些操作期间不执行真空或任何其他维护程序
- 也不用担心 txid 环绕问题
当使用 oracle 时,v$transaction 来拯救... 但是在 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
然后查看结果。如果它 returns 为零,则提交删除操作...如果结果为非零,则回滚事务,您无需担心未提交的事务
注: 这是为了检查从触发器接收并发送到另一个外部程序(java)的事务 ID 是否已提交且未回滚并且数据库会话不同...
如果您看到 xmin=123456
并且您的 txid_current() <> 123456
是 - 那么事务 123456 已提交。
postgres 中没有 transactionId
这样的列。
xmax
的测试是错误的。
UPDATE
或 DELETE
标记为无效时,xmax
被设置。意思是后面的交易ID的交易都看不到这个元组,一旦再也看不到它就可以回收
如果事务被回滚,xmax
的值不会被重置——事务状态存储在提交日志中,并且元组仍然可见其他。
但是xmax
也是用来存储行锁的
因此,如果您可以在 xmax = '123456'
处看到一个元组,则表示以下之一:
元组已删除或更新,事务已提交,但您的事务快照较旧,因此您仍然看到旧元组。
元组被删除或更新,事务被回滚。
元组被事务 123456 锁定,例如
SELECT ... FOR UPDATE
.
另一方面,如果您看到带有 xmin = '123456'
的元组并且这不是您当前的事务,您可以确定该事务已提交。
所以你的测试应该是
SELECT count(*) FROM table1 WHERE xmin='123456';
但这是一个 糟糕的 查询。它强制对整个 table 进行顺序扫描,并且不允许在系统列上建立索引。
如果您使用的是 PostgreSQL 9.5 或更新版本,请考虑激活 track_commit_timestamp
and using the function pg_xact_commit_timestamp(xid)
。对于未提交的事务,它将 return NULL。