2011-12-06 22 views
0

我想要一个计数器,我会在每次新交易开始时重置为0。我希望在某些触发器中使用该计数器的值。因为postgres的临时序列是会话本地的,所以只有在同一会话中没有“并行”运行两个事务的可能性时,我才可以使用一个作为我的计数器。在Postgres中安全吗? (我想到的让我感到不确定的情况就像Oracle中的自治事务一样,在这种情况下,我的会话本地对象将被外部事务和内部自治事务共享,这会破坏我想要的对象的事务局部性)在postgres中,(错误)使用临时(会话本地)序列作为事务本地序列是否安全?

我知道我可以使用带有ON COMMIT DROP或DELETE ROWS的TEMP表,但是我想知道一个临时序列是否足够,至少在postgres中。

+0

那么你的问题到底是什么? “安全吗?”不够具体。你想实现什么? –

+0

我想知道一个会话本地对象是否可以以任何可能的方式同时被多个事务同时访问。我更详细地描述了我的问题的背景。对不起,如果不清楚。 – Paralife

回答

2

当前PostgreSQL不支持并行或自主事务,因此session ==事务,因此会话本地临时序列将一次只能由一个事务访问。

您现在可以模拟Pg中的自治事务的唯一方法是使用dblink建立到数据库的新连接。因为这也建立了一个新的和独立的会话,所以您无需担心dblink的任何问题。

目前,它是安全的(如果我已经解释了你想要的东西正确)。

从长远来看,希望引入自治事务作为真正的存储过程支持的一部分。这看起来还有很长的路要走,而且不清楚自治事务是否能够看到临时表和由其父代创建的序列。您必须等待观察,并准备好相应地调整您的方法,或许可以使用以当前事务标识(txid)命名的临时序列。

如果你愿意,你可以做到这一点;使用txid_current()函数获取当前事务ID。

编辑:不,txid不会跨保存点更改。

regress=> begin; 
BEGIN 
regress=> SELECT txid_current(); 
txid_current 
-------------- 
     346947 
(1 row) 

regress=> savepoint test; 
SAVEPOINT 
regress=> SELECT txid_current(); 
txid_current 
-------------- 
     346947 
(1 row) 

虽然我想那是依靠一个实现细节。

+0

虽然如此,但我没有这样做,因为我的印象是txid随保存点而变化。这不是真的吗? – Paralife

+0

@Paralife:另外,使用动态标识符操作很难使用列默认值或非动态SQL等功能。 –

+0

txid不会在保存点上发生变化 - 请参阅上文。如果你担心这个问题,你可以从txid和CURRENT_TIMESTAMP中建立一个标识符(正如txn start所固定的那样)。 [编辑:这是无稽之谈; txid仍然会改变。如果两个txns同时启动到定时器分辨率,则不能使用_just_时间戳。啊。只要依靠txid不要改变,并测试升级!] 我不认为这将是特别漂亮,但你可以包装它在一个简单的SQL函数,使它更容易使用的默认和非动态SQL,Erwin提到这是一个问题。 –

相关问题