Thread: Update is not atomic

Update is not atomic

From
Victor Wagner
Date:
Following problem is encountered in Postgersql 7.1.2 on Linux
(I haven't tested on Solaris, but it seems that it is
platform-independent)

If we are trying to update field with unique constraint on it
(for instance, primary key) update might fail depending on order
how individual rows are updated. This is clear violation of SQL standard,
which states that individual sql operators are atomic, and constraints
should be valid either before beginning or after completion of operator.

Problem can be demonstrated by following example

create table a (a numeric primary key);
insert into a values (1);
insert into a values (2);
insert into a values (3);
insert into a values (4);
update a set a=a+1 where a>2;
ERROR:  Cannot insert a duplicate key into unique index a_pkey

Same statement sequence in Oracle (8.1.5.1) produces expected result:
2 rows updated

SQL> select * from a;

         A
----------
         1
         2
         4
         5



--
Victor Wagner            vitus@ice.ru
Chief Technical Officer        Office:7-(095)-748-53-88
Communiware.Net         Home: 7-(095)-135-46-61
http://www.communiware.net      http://www.ice.ru/~vitus

Re: Update is not atomic

From
Peter Eisentraut
Date:
Victor Wagner writes:

> create table a (a numeric primary key);
> insert into a values (1);
> insert into a values (2);
> insert into a values (3);
> insert into a values (4);
> update a set a=a+1 where a>2;
> ERROR:  Cannot insert a duplicate key into unique index a_pkey

This is a known problem with unique contraints, but it's not easy to fix
it.

--
Peter Eisentraut   peter_e@gmx.net   http://funkturm.homeip.net/~peter

Re: Update is not atomic

From
Victor Wagner
Date:
On Wed, 20 Jun 2001, Peter Eisentraut wrote:

> From: Peter Eisentraut <peter_e@gmx.net>
> Subject: Re: [BUGS] Update is not atomic
>
> Victor Wagner writes:
>
> > create table a (a numeric primary key);
> > insert into a values (1);
> > insert into a values (2);
> > insert into a values (3);
> > insert into a values (4);
> > update a set a=a+1 where a>2;
> > ERROR:  Cannot insert a duplicate key into unique index a_pkey


> This is a known problem with unique contraints, but it's not easy to fix
> it.

Is there any known workaround?
Like specifying order  of updates?



--
Victor Wagner            vitus@ice.ru
Chief Technical Officer        Office:7-(095)-748-53-88
Communiware.Net         Home: 7-(095)-135-46-61
http://www.communiware.net      http://www.ice.ru/~vitus

RE: Update is not atomic

From
"Mikheev, Vadim"
Date:
> Problem can be demonstrated by following example
> 
> create table a (a numeric primary key);
> insert into a values (1);
> insert into a values (2);
> insert into a values (3);
> insert into a values (4);
> update a set a=a+1 where a>2;
> ERROR:  Cannot insert a duplicate key into unique index a_pkey

We use uniq index for UK/PK but shouldn't. Jan?

Vadim


Re: [HACKERS] RE: Update is not atomic

From
Jan Wieck
Date:
Mikheev, Vadim wrote:
> > Problem can be demonstrated by following example
> >
> > create table a (a numeric primary key);
> > insert into a values (1);
> > insert into a values (2);
> > insert into a values (3);
> > insert into a values (4);
> > update a set a=a+1 where a>2;
> > ERROR:  Cannot insert a duplicate key into unique index a_pkey
>
> We use uniq index for UK/PK but shouldn't. Jan?
   What  else  can  you  use  than  an  index? A "deferred until   statement end" trigger checking for  duplicates?
Think it'd   have a real bad performance impact.
 
   Whatever  the  execution order might be, the update of '3' to   '4' will see the other '4' as existent WRT the scan
commandId  and  given snapshot - right? If we at the time we now fire up   the ERROR add the key, the  index  and  heap
to  a  list  of   "possible dupkeys", that we'll check at the end of the actual   command, the above would work. The
check at  statement  end   would have to increment the commandcounter and for each entry   do an index scan with the
key,counting the number of  found,   valid heap tuples.
 
   Well,  with  some  million rows doing a "set a = a + 1" could   run out of memory. So this would be something that'd
work in   the  sandbox  and  for non-broken applications (tm). Maybe at   some level (when we escalate the lock to a
fulltable  lock?)   we  simply  forget  about  single  keys, but have a new index   access function that checks the
entireindex for  uniqueness.
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com