Re: Best approach for a "gap-less" sequence
От | Dawid Kuroczko |
---|---|
Тема | Re: Best approach for a "gap-less" sequence |
Дата | |
Msg-id | 758d5e7f0608161347m76a8c461s834246709eb51d63@mail.gmail.com обсуждение исходный текст |
Ответ на | Best approach for a "gap-less" sequence (Jorge Godoy <jgodoy@gmail.com>) |
Ответы |
Re: Best approach for a "gap-less" sequence
Re: Best approach for a "gap-less" sequence |
Список | pgsql-general |
On 8/12/06, Jorge Godoy <jgodoy@gmail.com> wrote: > I was trying to solve a problem on an old system and realized that there might > be some better approach for doing what I need. > > We have some documents that need to be ordered sequentially and without gaps. > I could use a sequence, but if the transaction fails then when I rollback the > sequence will already have been incremented. > > So, today I have a control table and I acquire a SHARE ROW EXCLUSIVE lock to > it, read the value, increase it, do what I need and then I COMMIT the > transaction, ensuring that the sequence has no gaps. > > Is there a better way to guarantee that there will be no gaps in my sequence > if something goes wrong with my transaction? Hmm, I would do it this way: -- First prepare a table for keeping gapless sequence, say: CREATE TABLE gapless_seq ( gseq_name varchar(256) PRIMARY KEY, gseq_value integer NOT NULL ); -- ...and populate it: INSERT INTO gapless_seq VALUES('tax_id', '1'); -- then create a function to retrieve the values: CREATE FUNCTION gseq_nextval(t text) RETURNS integer AS $$ DECLARE n integer; BEGIN SELECT INTO n gseq_value+1 FROM gapless_seq WHERE gseq_name = t FOR UPDATE; UPDATE gapless_seq SET gapless_value = n WHERE gseq_name = t; RETURN n; END; $$ STABLE LANGUAGE PLpgsql; -- ...and use it as default in table definiton CREATE TABLE taxdata ( tax_id integer PRIMARY KEY DEFAULT gseq_nextval('tax_id'), customer text, when timestamptz ); ...etc. SELECT ... FOR UPDATE woud ensure a row lock on "gapless sequence", a PLpgsql function would make a nice wrapper for it (so it would be usable more or less similar to real sequences), and it should work. I did not test the code right now, but I've written something similar to it some time ago, and it worked fine. Remember to vacuum gapless_seq table frequently and don't expect stellar performance from it. Regards, Dawid
В списке pgsql-general по дате отправления: