Re: How to create "auto-increment" field WITHOUT a sequence object?

Поиск
Список
Период
Сортировка
От Dmitriy Igrishin
Тема Re: How to create "auto-increment" field WITHOUT a sequence object?
Дата
Msg-id BANLkTinr+T_NFQxbVbZCxm+hn6O+UpxyOA@mail.gmail.com
обсуждение исходный текст
Ответ на Re: How to create "auto-increment" field WITHOUT a sequence object?  (Chris Travers <chris.travers@gmail.com>)
Ответы Re: How to create "auto-increment" field WITHOUT a sequence object?  (Chris Travers <chris.travers@gmail.com>)
Список pgsql-general
Hey Chris,

The suggestion of using for
update is a good one, but it doesn't entirely get rid of the problem,
which is inherent in ensuring gapless numbering in a system with
concurrent transactions.
Why not?

I mean the following solution:

CREATE TABLE myseq(tabnm text not null, lastid integer not null);

INSERT INTO myseq SELECT 'mytab', 0; -- initialization

CREATE OR REPLACE FUNCTION public.myseq_nextval(a_tabnm text)
 RETURNS integer
 LANGUAGE sql
 STRICT
AS $function$
UPDATE myseq SET lastid = li + 1 FROM
  (SELECT lastid li FROM myseq WHERE tabnm = $1 FOR UPDATE) foo
  RETURNING lastid;
$function$

-- Test

dmitigr=> BEGIN;
BEGIN
dmitigr=> SELECT myseq_nextval('mytab');
 myseq_nextval
---------------
             1
(1 row)

dmitigr=> ROLLBACK;
ROLLBACK
dmitigr=> SELECT * FROM myseq;
 tabnm | lastid
-------+--------
 mytab |      0
(1 row)

So, with this approach you'll get a lock only on INSERT.

dmitigr=> CREATE TABLE mytab(id integer not null DEFAULT myseq_nextval('mytab'));
CREATE TABLE
dmitigr=> INSERT INTO mytab DEFAULT VALUES;
INSERT 0 1
dmitigr=> INSERT INTO mytab DEFAULT VALUES;
INSERT 0 1
dmitigr=> SELECT * FROM mytab;
 id
----
  1
  2
(2 rows)


--
// Dmitriy.


В списке pgsql-general по дате отправления:

Предыдущее
От: mona attariyan
Дата:
Сообщение: statically compiling postgres and problem with initdb
Следующее
От: Chris Travers
Дата:
Сообщение: Re: How to create "auto-increment" field WITHOUT a sequence object?