41

私はテーブルを持っています

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

ご覧のとおり、シーケンスはトランザクション ロールバックの影響を受けていないようです。トランザクションがコミットされてから行が削除されたかのように、それらは増加し続けます。シーケンスがこのように動作するのを防ぐ方法はありますか?

4

2 に答える 2

57

シーケンスをロールバックするのは得策ではありません。2 つのトランザクションが同時に発生し、それぞれが一意の ID にシーケンスを使用しているとします。2 番目のトランザクションがコミットされ、最初のトランザクションがロールバックされた場合、2 番目のトランザクションは "2" の行を挿入し、最初のトランザクションはシーケンスを "1" にロールバックします。

そのシーケンスが再度使用されると、シーケンスの値が「2」になり、一意の制約の問題が発生する可能性があります。

于 2010-01-19T18:25:36.250 に答える
8

いいえ、ありません。このページの下部にある注を参照してください。とにかくそんなことをするのは悪い考えです。2 つのトランザクションが同時に実行され、それぞれが 1 つの行を挿入する場合、異なる ID を持つ行を挿入する必要があります。

于 2010-01-19T18:27:52.967 に答える