2010-01-19 77 views
18

我有一个表序列不受交易影响?

create table testtable(
    testtable_rid serial not null, 
    data integer not null, 
    constraint pk_testtable primary key(testtable_rid) 
); 

因此,可以说我做这个代码约20倍:

begin; 
insert into testtable (data) values (0); 
rollback; 

,然后我做

begin; 
insert into testtable (data) values (0); 
commit; 

最后一个

select * from testtable 
 
Result: 
row0: testtable_rid=21 | data=0 
Expected result: 
row0: testtable_rid=1 | data=0 

如您所见,序列似乎不受事务回滚的影响。他们继续增加,就好像事务已被提交,然后该行被删除。有什么方法可以防止序列以这种方式行事?

回答

26

回滚序列不是一个好主意。设想两个事务同时发生,每个事务都使用唯一ID的序列。如果第二个事务提交并且第一个事务回滚,那么第二个事务将“2”插入一行,而第一个事务将序列回滚到“1”。

如果再次使用该序列,则序列的值将变为“2”,这可能导致唯一的约束问题。

+2

如果第二个事务提交,这个事务应该得到序列号1.由于第一个事务回滚了,所以第一个事务没有序列号。当然,PostgreSQL没有实现这一点,Oracle也没有实现,但是对于事务性排序没有概念上的限制,只有实施中的限制。 – Hartmut 2014-12-18 00:51:03

5

不,没有。请参阅this page底部的注释。无论如何,做这样的事情是一个坏主意。如果您有两个事务同时运行,每个插入一行,您希望它们插入具有不同ID的行。