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.