Re: [pgsql-ru-general] атомарно сохранить или проапдейтить

From: Nikolay Samokhvalov <samokhvalov(at)gmail(dot)com>
To: "Dmitry E(dot) Oboukhov" <unera(at)debian(dot)org>
Cc: pgsql-ru-general(at)postgresql(dot)org
Subject: Re: [pgsql-ru-general] атомарно сохранить или проапдейтить
Date: 2012-06-20 21:13:35
Message-ID: CANNMO+JeS3zjcQcxAM0zszTz-4Tm5W0Af5sdjx2mYV95+wgRZA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-ru-general

1) можно поменять местами -- пробуем вставлять, если ошибка, то делаем
update
2) немного более правильно делать это "ближе к серверу", для этого можно
написать plpgsql-функцию, см Example 39-2. Exceptions with UPDATE/INSERT
http://www.postgresql.org/docs/9.1/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING
3) ещё правильнее (и моднее) -- это использовать CTE
http://vibhorkumar.wordpress.com/2011/10/26/upsertmerge-using-writable-cte-in-postgresql-9-1/

2012/6/20 Dmitry E. Oboukhov <unera(at)debian(dot)org>

>
> приходят внешние данные с уникальным ID (uuid)
>
> нужно эту запись либо создать, либо проапдейтить новыми значениями
>
> делал так:
>
> dbh->begin_work; # начали транзакцию
>
> my $record = dbh->single( # попытка апдейта
> q{
> UPDATE
> table
> SET
> some=?
> WHERE
> eid=?
> RETURNING *
> }, $val, $eid
> );
>
> unless ($record) { # инсерт после неудачи апдейта
> my $record = dbh->single(
> q{
> INSERT INTO
> table
> (eid, some)
>
> VALUES
> (?, ?)
> RETURNING *
> }, $eid, $val
> );
>
> }
>
> dbh->commit; # коммит транзакции
>
>
>
> то есть в транзакции пытаемся сперва сделать апдейт имеющегося, а если
> его нет в БД то затем делаем insert.
>
> так вот при таком подходе при приходе одновременных запросов иногда
> падает на втором insert'е с жалобой что такой ключ уже существует.
>
> как правильно решить данную проблему?
>
> --
>
> . ''`. Dmitry E. Oboukhov
> : :’ : email: unera(at)debian(dot)org jabber://UNera(at)uvw(dot)ru
> `. `~’ GPGKey: 1024D / F8E26537 2006-11-21
> `- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
>
> iEYEAREDAAYFAk/iF0cACgkQq4wAz/jiZTcyfACg0YDwJvZbxKBenjotM7WDdWL/
> YJoAoNgQ6tz13jtNGlkIYdf4XGoATD/Y
> =OQgr
> -----END PGP SIGNATURE-----
>
>

In response to

Responses

Browse pgsql-ru-general by date

  From Date Subject
Next Message Nikolay Samokhvalov 2012-06-20 21:17:36 Re: [pgsql-ru-general] атомарно сохранить или проапдейтить
Previous Message Dmitry E. Oboukhov 2012-06-20 18:32:39 атомарно сохранить или проапдейтить