From: | Dmitriy Igrishin <dmitigr(at)gmail(dot)com> |
---|---|
To: | Chris Travers <chris(dot)travers(at)gmail(dot)com> |
Cc: | Postgres General <pgsql-general(at)postgresql(dot)org> |
Subject: | Re: How to create "auto-increment" field WITHOUT a sequence object? |
Date: | 2011-07-01 08:28:47 |
Message-ID: | BANLkTinb6mAQOLcdLW3V8xZ0ubYq16zU0w@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
2011/7/1 Chris Travers <chris(dot)travers(at)gmail(dot)com>
> On Fri, Jul 1, 2011 at 1:16 AM, Dmitriy Igrishin <dmitigr(at)gmail(dot)com>
> wrote:
> > 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?
>
> Just because it locks less doesn't mean that it doesn't lock.
>
> The point is: if gaps are acceptable then the sequences which exist
> outside of transactions are idea. If gaps are not acceptable, you
> have to lock and force transactions through the system serially which
> means a possibility of deadlocks and performance issues. These issues
> are inherent in gapless numbering because you can't get a gapless
> sequence when things roll back without such locks.
>
Then I don't clearly understand the existence of locks (the LOCK
command, SELECT FOR UPDATE clause and so on) if the usage
of them gives only problems...
>
> > 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.
>
> True. But the point us that you MUST lock on insert to get gapless
> sequences, and this creates inherent problems in terms of performance
> and concurrency, so that you should not use it unless you really have
> no other choice (i.e. because the tax authorities demand it).
>
Sure, but, again, why LOCK and SELECT FOR UPDATE exists ?
>
> Best Wishes,
> Chris Travers
>
--
// Dmitriy.
From | Date | Subject | |
---|---|---|---|
Next Message | Craig Ringer | 2011-07-01 08:34:36 | Re: How to create "auto-increment" field WITHOUT a sequence object? |
Previous Message | Craig Ringer | 2011-07-01 08:26:18 | Re: statically compiling postgres and problem with initdb |