Was passiert in Schritt 6?
Transaktion A sieht myfunc()
sofort die aktualisierte Definition der Funktion . (Aber sehen Sie den Effekt des Caches unten.)
Und wenn die Funktion in Schritt 4 gelöscht wird, anstatt geändert zu werden, wird Schritt 6 fehlschlagen oder erfolgreich sein?
Es wird scheitern. (Aber sehen Sie den Effekt des Caches unten.)
Postgres-DDL-Befehle sind vollständig transaktional. Während Transaktion B nicht festgeschrieben wird, werden für beide Transaktionen weiterhin unterschiedliche Versionen der Funktion angezeigt. Aber gleichzeitig ablaufenden Transaktionen tun sehen engagierte Änderungen in Systemkatalogen. In der Standardisolationsstufe scheint dies offensichtlich zu sein READ COMMITTED
. Aber Sie können dies nicht einmal mit Isolationsstufen REPEATABLE READ
oder verhindern SERIALIZABLE
.
Wenn Sie die Funktion in Transaktion A aufgerufen haben sollten, bevor Transaktion B eine Änderung festgeschrieben hat, kann der lokale Cache stören. In meinen Tests arbeitete ein weiterer Anruf mit der zwischengespeicherten (alten) Funktion, bevor der nächste Anruf die Änderung bemerkte und entsprechend antwortete.
Ich habe keine Dokumentation gefunden, wie sich der Systemkatalog-Cache genau dafür verhält (möglicherweise noch irgendwo vorhanden). Ich bin nicht davon überzeugt, dass das letzte Bit (ein weiterer Anruf aus dem Cache beantwortet) das bestmögliche Verhalten ist.
Übrigens können Ihre Schritte 3. - 5. ohne Unterschied auf nur 4. reduziert werden. Explizite oder implizite Transaktions-Wrapper funktionieren genauso:
3. Starten Sie eine Transaktion von Client B aus.
4. Verwenden Sie in Transaktion B die Funktion "Erstellen oder Ersetzen", um die Definition von myfunc () zu überarbeiten.
5. Übernehmen Sie Transaktion B.