atomic function

Started by Mageover 20 years ago4 messagesgeneral
Jump to latest
#1Mage
mage@mage.hu

Hello!

What's wrong with this function?

public | common_adviewnum_increase | integer | bigint,
character varying | postgres | plpgsql |
declare
row record;
result int;
begin
select into row viewnum from common_adviewnum where adid = $1
and site = $2 and day = now()::date;
if found then
result = row.viewnum + 1;
update common_adviewnum set viewnum = result where adid
= $1 and site = $2 and day = now()::date;
else
result = 1;
insert into common_adviewnum (adid, site, day, viewnum)
values ($1, $2, now()::date, result);
end if;
return result;
end;

Every 2-3 day I get this in the server log:

2005-08-12 19:08:43: ERROR: duplicate key violates unique constraint
"common_adviewnum_adid_site_day_index"
CONTEXT: SQL statement "insert into common_adviewnum (adid, site, day,
viewnum) values ( $1 , $2 , now()::date, $3 )"
PL/pgSQL function "common_adviewnum_increase" line 11 at SQL statement
select common_adviewnum_increase(820434,'H');

Mage

#2Dennis Bjorklund
db@zigo.dhs.org
In reply to: Mage (#1)
Re: atomic function

On Mon, 15 Aug 2005, Mage wrote:

2005-08-12 19:08:43: ERROR: duplicate key violates unique constraint
"common_adviewnum_adid_site_day_index"

Between your select and your insert someone else inserted a row making the
insert fail.

See this example of how you can update or insert depending on what is in
the table:

http://developer.postgresql.org/docs/postgres/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE

If you don't have 8.0 so you can do as the example you need to lock the
table so no one else can insert between your select and your insert.

--
/Dennis Bj�rklund

#3Tino Wildenhain
tino@wildenhain.de
In reply to: Mage (#1)
Re: atomic function

Mage schrieb:

Hello!

What's wrong with this function?

public | common_adviewnum_increase | integer | bigint,
character varying | postgres | plpgsql |
declare
row record;
result int;
begin
select into row viewnum from common_adviewnum where adid = $1 and
site = $2 and day = now()::date;
if found then
result = row.viewnum + 1;
update common_adviewnum set viewnum = result where adid =
$1 and site = $2 and day = now()::date;
else
result = 1;
insert into common_adviewnum (adid, site, day, viewnum)
values ($1, $2, now()::date, result);
end if;
return result;
end;

Every 2-3 day I get this in the server log:

2005-08-12 19:08:43: ERROR: duplicate key violates unique constraint
"common_adviewnum_adid_site_day_index"
CONTEXT: SQL statement "insert into common_adviewnum (adid, site, day,
viewnum) values ( $1 , $2 , now()::date, $3 )"
PL/pgSQL function "common_adviewnum_increase" line 11 at SQL statement
select common_adviewnum_increase(820434,'H');

You might find out by replacing this function with something you find
here:

http://www.postgresql.org/docs/current/static/functions-sequence.html

#4Mage
mage@mage.hu
In reply to: Dennis Bjorklund (#2)
Re: atomic function

Dennis Bjorklund wrote:

On Mon, 15 Aug 2005, Mage wrote:

2005-08-12 19:08:43: ERROR: duplicate key violates unique constraint
"common_adviewnum_adid_site_day_index"

Between your select and your insert someone else inserted a row making the
insert fail.

I see. I thought that the function will be atomic but I was wrong.

See this example of how you can update or insert depending on what is in
the table:

http://developer.postgresql.org/docs/postgres/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE

Or should I simply lock the table?

Mage