Nie znam żadnego bezpiecznego, skutecznego sposobu robienia tego, czego chcesz. Naprawdę powinieneś wybrać, czy chcesz zdefiniować klucze samodzielnie, czy użyć wygenerowanych kluczy i trzymać się jednej lub drugiej strategii.
Jeśli nie masz nic przeciwko okropnej współbieżności, możesz LOCK TABLE thetable
, rób swoją pracę, setval
sekwencja identyfikatora tabeli do następnej wolnej wartości po wstawieniu i commit
aby zwolnić blokadę. Jednak nadal będzie to powodować problemy z aplikacjami, które jawnie wywołują nextval
(jak wiele ORM-ów) zamiast pozwolić bazie danych zdefiniować wartość przez pominięcie jej w ?INSERT
lista kolumn lub jawne nazwanie jej jako DEFAULT
.
W przeciwnym razie możesz mieć swój kod (lub funkcję pomocniczą PL/PgSQL) wstawić w pętli ponawiania, która zwiększa klucz i próbuje ponownie, gdy wystąpi błąd integralności. Ta strategia nie zadziała, jeśli potrzebujesz zrobić więcej niż tylko jedną wstawkę na transakcję. Ponadto w SERIALIZABLE
tryb izolacji Nie sądzę, że możesz to zrobić z PL/PgSQL, musisz użyć pętli ponawiania po stronie klienta, aby obsłużyć błędy serializacji.
To okropny pomysł. Konsekwentnie używaj kluczy zdefiniowanych przez aplikację lub kluczy zdefiniowanych w bazie danych. Nie mieszaj tych dwóch.