Nie, dokumentacja jest niepoprawna. Skorzystanie z samej transakcji nie pozwala na uniknięcie tego problemu. Gwarantuje to tylko, że cała transakcja zostanie wycofana, jeśli wystąpi wyjątek - aby w bazie danych nie było niespójnego stanu.
Do unikaj tego problemu, musisz zablokować tabelę - wewnątrz transakcji, ponieważ wszystkie blokady są zwalniane na końcu transakcji. Coś takiego:
BEGIN;
LOCK TABLE mytbl IN SHARE MODE;
-- do your find_or_create here
COMMIT;
Ale to nie jest magiczne lekarstwo na wszystko. Może to być problem z wydajnością i mogą występować zakleszczenia (równoczesne transakcje wzajemnie próbujące zablokować zasoby, które zostały już zablokowane). PostgreSQL wykryje taki warunek i anuluje wszystkie oprócz jednej z konkurencyjnych transakcji. Musisz być przygotowany na ponowienie operacji w przypadku niepowodzenia.
The PostgreSQL manual about locks.
Jeśli nie masz dużo współbieżności Państwo może też po prostu zignorować problem. Przedział czasowy jest bardzo mały, więc bardzo rzadko się zdarza. Jeśli zauważysz zduplikowany błąd naruszenia klucza, który nie zaszkodzi, to również to omówiłeś.
Inne użyteczne strony. Dokumenty: http://www.postgresql.org/docs/current/interactive/mvcc.html Wersja PostgreSQL 9.1 lub późniejsza wersja szeregowalna: http://wiki.postgresql.org/wiki/SSI Inne poziomy izolacji lub wersje PostgreSQL: http : //www.postgresql.org/files/developer/concurrency.pdf – kgrittn
Ale jaki jest właściwy sposób na złapanie "duplikatu błędu naruszenia klucza" w DBIC? –
@eugeney: Przypuszczam, że otwierasz nowe pytanie zamiast komentarza. Zawsze możesz utworzyć link do tego, by zapisać sobie trochę pisania. –