PostgreSQL:查看当前事务是否创建了一行
PostgreSQL: find out if a row has been created by the current transaction
是否可以查明 table 中的一行是否已由当前事务创建(因此对于其他事务尚不可见,因为当前事务仍处于活动状态)?
我的用例:我正在向数据库添加事件日志记录。这是在 plpgsql 触发器中完成的。事件 table 中的一行如下所示:(event id:serial, event action:text, count:integer:default 1)
.
现在,我的问题背后的原因是:如果此事务已创建特定行(很可能在另一个触发器中),我可以增加计数而不是在事件中创建新行 table .
您可能会考虑这样的事情:
create table ConnectionCurrentAction (
connectionID int primary key,
currentActionID uuid
)
然后在交易开始时:
delete ConnectionCurrentAction where connectionID = pg_backend_pid()
insert ConnectionCurrentAction(connectionID, currentActionID)
select pg_backend_pid(), uuid_generate_v4()
你可以把它包装在一个叫做 say 的过程中,audit_action_begin
注意:您可以改为选择通过删除此处的删除来强制执行明确创建 "action" 的要求。
在交易结束时,执行 audit_action_end
:
delete ConnectionCurrentAction where connectionID = pg_backend_pid()
每当你想知道当前的交易:
(select currentActionID from ConnectionCurrentAction where connectionID - pg_backend_pid()(
您可以将其包装在一个函数中 audit_action_current()
然后您可以将 currentActionID 放入您的日志中,这将使您能够识别是否在当前操作中创建了一行。这还将允许您识别在当前逻辑操作中不同审计表中的行是在何处创建的。
如果您不想使用 uuid,这里也可以使用序列。我喜欢uuid。
您可以像这样查找日志条目:
SELECT ...
FROM tablename
WHERE xmin = current_txid() % (2^32)::bigint;
这将找到在当前事务中添加或修改的所有行。
缺点是这将强制对整个系统进行顺序扫描 table,并且您无法避免这种情况,因为您无法在系统列上创建索引。
因此,您可以在 table 中添加一个额外的列 xid
,每当插入或更新一行时,该列都会用 txid_current()::bigint
填充。这样的列可以被索引并有效地用于搜索:
SELECT ...
FROM tablename
WHERE xid = current_txid();
是否可以查明 table 中的一行是否已由当前事务创建(因此对于其他事务尚不可见,因为当前事务仍处于活动状态)?
我的用例:我正在向数据库添加事件日志记录。这是在 plpgsql 触发器中完成的。事件 table 中的一行如下所示:(event id:serial, event action:text, count:integer:default 1)
.
现在,我的问题背后的原因是:如果此事务已创建特定行(很可能在另一个触发器中),我可以增加计数而不是在事件中创建新行 table .
您可能会考虑这样的事情:
create table ConnectionCurrentAction (
connectionID int primary key,
currentActionID uuid
)
然后在交易开始时:
delete ConnectionCurrentAction where connectionID = pg_backend_pid()
insert ConnectionCurrentAction(connectionID, currentActionID)
select pg_backend_pid(), uuid_generate_v4()
你可以把它包装在一个叫做 say 的过程中,audit_action_begin
注意:您可以改为选择通过删除此处的删除来强制执行明确创建 "action" 的要求。
在交易结束时,执行 audit_action_end
:
delete ConnectionCurrentAction where connectionID = pg_backend_pid()
每当你想知道当前的交易:
(select currentActionID from ConnectionCurrentAction where connectionID - pg_backend_pid()(
您可以将其包装在一个函数中 audit_action_current()
然后您可以将 currentActionID 放入您的日志中,这将使您能够识别是否在当前操作中创建了一行。这还将允许您识别在当前逻辑操作中不同审计表中的行是在何处创建的。
如果您不想使用 uuid,这里也可以使用序列。我喜欢uuid。
您可以像这样查找日志条目:
SELECT ...
FROM tablename
WHERE xmin = current_txid() % (2^32)::bigint;
这将找到在当前事务中添加或修改的所有行。
缺点是这将强制对整个系统进行顺序扫描 table,并且您无法避免这种情况,因为您无法在系统列上创建索引。
因此,您可以在 table 中添加一个额外的列 xid
,每当插入或更新一行时,该列都会用 txid_current()::bigint
填充。这样的列可以被索引并有效地用于搜索:
SELECT ...
FROM tablename
WHERE xid = current_txid();