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

Поиск
Список
Период
Сортировка
От Nikolay Samokhvalov
Тема Re: [pgsql-ru-general] атомарно сохранить или проапдейтить
Дата
Msg-id CANNMO+KOCWuH0zuawvZThz33S_7k9u+kMXyLqsY8tfEE8AG=_A@mail.gmail.com
обсуждение исходный текст
Ответ на Re: [pgsql-ru-general] атомарно сохранить или проапдейтить  (Nikolay Samokhvalov <samokhvalov@gmail.com>)
Список pgsql-ru-general
кстати, у нашего польского собрата по футбольному несчастью depesz-а совсем свежий пост на эту тему, советую

http://www.depesz.com/2012/06/10/why-is-upsert-so-complicated/

2012/6/21 Nikolay Samokhvalov <samokhvalov@gmail.com>
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@debian.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@debian.org jabber://UNera@uvw.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-----



В списке pgsql-ru-general по дате отправления:

Предыдущее
От: Nikolay Samokhvalov
Дата:
Сообщение: Re: [pgsql-ru-general] атомарно сохранить или проапдейтить
Следующее
От: John Nash
Дата:
Сообщение: WebSphere Application Server support for postgres