Ik ken geen veilige, efficiënte manier om te doen wat je wilt. Je moet echt kiezen of je de sleutels zelf wilt definiëren of gegenereerde sleutels wilt gebruiken en je aan de ene of de andere strategie wilt houden.
Als je het niet erg vindt dat er vreselijke gelijktijdigheid is, kun je LOCK TABLE thetable
, doe je werk, setval
de identificatiereeks van de tabel naar de volgende vrije waarde na wat u hebt ingevoegd, en commit
om het slot te ontgrendelen. Dat zal echter nog steeds problemen veroorzaken met apps die expliciet nextval
. aanroepen (zoals veel ORM's) in plaats van de database de waarde te laten definiëren door deze weg te laten uit de ?INSERT
kolomlijst of expliciet benoemen als DEFAULT
.
Anders zou je je code (of een PL/PgSQL-helperfunctie) kunnen laten invoegen in een nieuwe lus die de sleutel verhoogt en het opnieuw probeert wanneer er een integriteitsfout optreedt. Deze strategie werkt niet als u meer moet doen dan alleen die ene invoeging per transactie. Verder in SERIALIZABLE
isolatiemodus Ik denk niet dat je het kunt doen met PL/PgSQL, je moet een client-side retry-lus gebruiken om serialisatiefouten af te handelen.
Het is een verschrikkelijk idee. Gebruik consistent door de toepassing gedefinieerde sleutels of door de database gedefinieerde sleutels. Meng de twee niet.