事务不影响序列吗?

48

我有一张表格

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
结果:
row0:testtable_rid=21 | 数据=0
期望结果:
row0:testtable_rid=1 | 数据=0

正如您所看到的,似乎序列不受事务回滚的影响。它们继续增加,就像事务被提交然后行被删除一样。有没有什么办法可以防止序列以这种方式行为?
2个回答

66

回滚序列并不是一个好主意。想象一下同时发生的两个事务,每个都使用序列作为唯一标识符。如果第二个事务提交而第一个事务回滚,则第二个插入了一个值为“2”的行,而第一个将序列回滚到“1”。

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


13
如果第二个交易提交了,那么这个交易应该获得序列号 1。由于第一个交易已回滚,因此不会为第一个交易采用任何序列号。当然,PostgreSQL 和 Oracle 都没有实现这一点,但是我认为在事务排序方面没有概念上的限制,只有实现上的限制。 - Hartmut Pfarr
7
@HartmutP,你的观点是错误的。限制条件是使用序列生成唯一数字时不能扫描任何数据结构来确定该数字是否正在使用。确保唯一性的唯一方法是在第一次获取值时将其丢弃,即使获得它们的事务没有提交。 - jpmc26
2
这取决于事务隔离级别。可串行化隔离将防止您所解释的问题。 - ceving

11

没有这样的功能。请查看该页面底部的注释。不建议这样做。如果同时运行两个事务,每个事务插入一行数据,你希望它们插入具有不同ID的行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接