【问题标题】:Sequences not affected by transactions?序列不受交易影响?
【发布时间】:2011-01-06 22:39:45
【问题描述】:

我有一张桌子

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
结果: 第 0 行:testtable_rid=21 |数据=0 预期结果: 第 0 行:testtable_rid=1 |数据=0

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

【问题讨论】:

    标签: postgresql transactions rollback database-sequence


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 如果第二个事务提交,这个事务应该得到序列号 1。由于第一个事务回滚,第一个事务将没有序列号。当然,PostgreSQL 没有实现,Oracle 也没有,但恕我直言,对事务排序没有概念上的限制,只有实现中的限制。
      • @HartmutP。你不正确。约束是序列用于生成唯一编号无需扫描任何数据结构以确定该编号是否正在使用。在不进行扫描的情况下确保唯一性的唯一方法是在第一次获取时丢弃值,即使获取它们的事务没有提交。
      • 取决于事务隔离级别。 Serializable Isolation 会避免这个问题,你已经解释过了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多