Thread: locking on database updates

locking on database updates

From
Gary Stainburn
Date:
Hi All,

I have a number of tables in my database where the key is an int4 into which I place a unique sequential number.  I
havelearned from part experience (although not on pgsql) not to use auto-generated numbers as it makes it a nightmare
torebuild corrupted databases.
 

I then have a parameter table with a single row in it containing the next available number for each table.  There will
eventuallybe approx 140 users on this database accessing from web browsers (apache->perl using CGI.pm and DBI/DBD::Pg)
andthe main table will be hit quite hard.
 

My question is this.  Is there a safe way of retrieving the next number from the parameter table in such a way that the
samenumber cannot be retrieved twice
 

Pseudo Code

Select & lock record
increment number
Update record
Unlock record
.......

-----------------------------------------
Gary Stainburn.
Work: http://www.ringways.co.uk gary.stainburn@ringways.co.uk
REVCOM: http://www.revcom.dhs.org http://www.revcom.org.uk gary.stainburn@revcom.org.uk
-----------------------------------------
The nice thing about standards is that there are so many of them to choose from. -- Andrew S. Tanenbaum
-----------------------------------------



Re: [INTERFACES] locking on database updates

From
Rich Shepard
Date:
On Mon, 6 Dec 1999, Gary Stainburn wrote:

> Pseudo Code
> 
> Select & lock record
> increment number
> Update record
> Unlock record
 What I learned from writing databases in Paradox/DOS is to change the
sequence so that steps 2 and 3 are switched. That is, wait until the record
is committed to be added, then grab the next number and assign it.
 The advantage is that if the record is not added (user changed her mind or
had to go do something else right away), the ID table is untouched. Also,
assigning the unique number just before writing the record means that the ID
table is locked, incremented and unlocked very quickly. No one is slowed
down by this process.

HTH,

Rich

Dr. Richard B. Shepard, President
                      Applied Ecosystem Services, Inc. (TM)             Making environmentally-responsible mining
happen.(SM)                               --------------------------------           2404 SW 22nd Street | Troutdale,
OR97060-1247 | U.S.A.+ 1 503-667-4517 (voice) | + 1 503-667-8863 (fax) | rshepard@appl-ecosys.com
 



Re: [INTERFACES] locking on database updates

From
Tom Lane
Date:
Gary Stainburn <gary.stainburn@ringways.co.uk> writes:
> My question is this.  Is there a safe way of retrieving the next
> number from the parameter table in such a way that the same number
> cannot be retrieved twice.

Use a SEQUENCE object for each "parameter table".  This gives you 
a well-tested, efficient generator mechanism.  It may be "auto
generated" but you do have the option of resetting the sequence's
nextval and so forth, so I don't see that there is a good reason
to build a SEQUENCE substitute by hand.
        regards, tom lane


Re: [INTERFACES] locking on database updates

From
Joseph Shraibman
Date:
Tom Lane wrote:

> Gary Stainburn <gary.stainburn@ringways.co.uk> writes:
> > My question is this.  Is there a safe way of retrieving the next
> > number from the parameter table in such a way that the same number
> > cannot be retrieved twice.
>
> Use a SEQUENCE object for each "parameter table".  This gives you
> a well-tested, efficient generator mechanism.  It may be "auto
> generated" but you do have the option of resetting the sequence's
> nextval and so forth, so I don't see that there is a good reason
> to build a SEQUENCE substitute by hand.
>
>                         regards, tom lane
>
> ************

Can you give an example of sql that creates a table with that?



Re: [INTERFACES] locking on database updates

From
Douglas Thomson
Date:
Joseph Shraibman <jks@p1.selectacast.net> writes:
> Tom Lane wrote:
> > Gary Stainburn <gary.stainburn@ringways.co.uk> writes:
> > > My question is this.  Is there a safe way of retrieving the next
> > > number from the parameter table in such a way that the same number
> > > cannot be retrieved twice.
> >
> > Use a SEQUENCE object for each "parameter table".  This gives you
> > a well-tested, efficient generator mechanism.  It may be "auto
> > generated" but you do have the option of resetting the sequence's
> > nextval and so forth, so I don't see that there is a good reason
> > to build a SEQUENCE substitute by hand.
>
> Can you give an example of sql that creates a table with that?

I created my sequence using code like:
    CREATE SEQUENCE name_map_seq START 1
and then used it as the default in another table:
    CREATE TABLE name_map (
        id INT DEFAULT nextval('name_map_seq'),
        name TEXT,
        info TEXT
    )
I also added a unique index to avoid possible mistakes:
    CREATE UNIQUE INDEX name_map_unq ON name_map (id)

If I just insert into the name_map table without supplying any
id:
    INSERT INTO name_map (name, info) VALUES ('some name', 'some info')
then I get the next sequence number filled in for the id attribute.

On the other hand, if I need to rebuild a table using the same id
values as before, I can simply provide a value explicitly, and then
the default is ignored:
    INSERT INTO name_map (id, name, info) VALUES (24, 'name', 'info')

If I need to find out what value my sequence is up to, I can extract
it using:
    SELECT last_value FROM name_map_seq

Finally, if I need to prime the sequence when reconstructing tables,
I use:
    SELECT setval('name_map_seq', 24)
(looks weird modifying a table with a SELECT, but it works!).

Hope this helps. Criticism welcome; I make no claim to be an expert
on either PostgreSQL or SQL in general, I just wanted to contribute
something by way of thanks for all the assistance I have received
from this list!

Doug.

Re: [INTERFACES] locking on database updates

From
Joseph Shraibman
Date:
Douglas Thomson wrote:

> Joseph Shraibman <jks@p1.selectacast.net> writes:
> > Tom Lane wrote:
> > > Gary Stainburn <gary.stainburn@ringways.co.uk> writes:
> > > > My question is this.  Is there a safe way of retrieving the next
> > > > number from the parameter table in such a way that the same number
> > > > cannot be retrieved twice.
> > >
> > > Use a SEQUENCE object for each "parameter table".  This gives you
> > > a well-tested, efficient generator mechanism.  It may be "auto
> > > generated" but you do have the option of resetting the sequence's
> > > nextval and so forth, so I don't see that there is a good reason
> > > to build a SEQUENCE substitute by hand.
> >
> > Can you give an example of sql that creates a table with that?
>
> I created my sequence using code like:
>     CREATE SEQUENCE name_map_seq START 1
> and then used it as the default in another table:
>     CREATE TABLE name_map (
>         id INT DEFAULT nextval('name_map_seq'),
>         name TEXT,
>         info TEXT
>     )
> I also added a unique index to avoid possible mistakes:
>     CREATE UNIQUE INDEX name_map_unq ON name_map (id)
>
> If I just insert into the name_map table without supplying any
> id:
>     INSERT INTO name_map (name, info) VALUES ('some name', 'some info')
> then I get the next sequence number filled in for the id attribute.
>
> On the other hand, if I need to rebuild a table using the same id
> values as before, I can simply provide a value explicitly, and then
> the default is ignored:
>     INSERT INTO name_map (id, name, info) VALUES (24, 'name', 'info')
>
> If I need to find out what value my sequence is up to, I can extract
> it using:
>     SELECT last_value FROM name_map_seq
>
> Finally, if I need to prime the sequence when reconstructing tables,
> I use:
>     SELECT setval('name_map_seq', 24)
> (looks weird modifying a table with a SELECT, but it works!).
>
> Hope this helps. Criticism welcome; I make no claim to be an expert
> on either PostgreSQL or SQL in general, I just wanted to contribute
> something by way of thanks for all the assistance I have received
> from this list!
>
> Doug.

Thanks.  I just wish the postgres documentation were a little better.  Does
anyone know of a SQL refrence on the web *anywhere*?  I've just started
programming in sql, and I can't even find one in a big Barnes & Noble.



Re: [INTERFACES] locking on database updates

From
Tom Lane
Date:
Douglas Thomson <dougt@mugc.cc.monash.edu.au> writes:
> Joseph Shraibman <jks@p1.selectacast.net> writes:
>> Can you give an example of sql that creates a table with that?

A couple footnotes on Doug's fine example:

> I created my sequence using code like:
>     CREATE SEQUENCE name_map_seq START 1
> and then used it as the default in another table:
>     CREATE TABLE name_map (
>         id INT DEFAULT nextval('name_map_seq'),
>         name TEXT,
>         info TEXT
>     )
> I also added a unique index to avoid possible mistakes:
>     CREATE UNIQUE INDEX name_map_unq ON name_map (id)

Declaring a column as "SERIAL" is a handy shortcut for exactly these
declarations: a sequence, a default value of nextval('sequence'), and
a unique index on the column.  (Plus a NOT NULL constraint, which you
might perhaps not want.)  You can reach in and inspect/modify the
sequence object for a SERIAL column just as if you'd made the sequence
by hand.

> On the other hand, if I need to rebuild a table using the same id
> values as before, I can simply provide a value explicitly, and then
> the default is ignored:
>     INSERT INTO name_map (id, name, info) VALUES (24, 'name', 'info')

Right.  Dumping and restoring the table with COPY commands works the
same way.  In fact, if you dump the database with pg_dump, you'll find
that the resulting script not only restores all the values of the "id"
column via COPY, but also recreates the current state of the sequence
object.
        regards, tom lane


Re: [INTERFACES] locking on database updates

From
Rich Shepard
Date:
On Mon, 6 Dec 1999, Joseph Shraibman wrote:

> Thanks.  I just wish the postgres documentation were a little better.  Does
> anyone know of a SQL refrence on the web *anywhere*?  I've just started
> programming in sql, and I can't even find one in a big Barnes & Noble.

Joe,
 I recommend Joe Celko's book, "Instant SQL Programming", published by Wrox
Press.
 Joe is a SQL expert who wrote (still writes?) columns for the database
magazines. He writes clearly and comprehensively.
 Highly recommended.

Rich

Dr. Richard B. Shepard, President
                      Applied Ecosystem Services, Inc. (TM)             Making environmentally-responsible mining
happen.(SM)                               --------------------------------           2404 SW 22nd Street | Troutdale,
OR97060-1247 | U.S.A.+ 1 503-667-4517 (voice) | + 1 503-667-8863 (fax) | rshepard@appl-ecosys.com
 



Re: [INTERFACES] locking on database updates

From
Thomas Lockhart
Date:
> Thanks.  I just wish the postgres documentation were a little better.

Um, if you were a bit more specific that would be helpful ;)

The topic you have asked about is in the docs somewhere; now that you
know the solution perhaps you can go back and suggest where in the
docs this should appear to make it clearer. Without looking, I'd
predict you will find something about the SERIAL type in the User's
Guide in the chapter on data types...

Good luck.
                    - Thomas

-- 
Thomas Lockhart                lockhart@alumni.caltech.edu
South Pasadena, California


Re: [INTERFACES] locking on database updates

From
Joseph Shraibman
Date:
Thomas Lockhart wrote:

> > Thanks.  I just wish the postgres documentation were a little better.
>
> Um, if you were a bit more specific that would be helpful ;)
>
> The topic you have asked about is in the docs somewhere; now that you
>

So it is.  I was looking under 'tutorial' and it was in 'postgres'