Ok, ich glaube, ich habe das herausgefunden. Das Problem liegt in einem seit langem bestehenden Problem mit Django und Psycopg2. Grundsätzlich gibt Psycopg2 automatisch eine BEGIN-Anweisung an die DB aus. Wenn Django jedoch glaubt, dass keine Datenänderung stattgefunden hat, wird es am Ende einer Transaktion kein COMMIT ausgeben.
Es gibt einige Lösungen für dieses Problem, siehe http://www. slideshare.net/OReillyOSCON/unbreaking-your-django-application für mehr Details. Idealerweise schalten Sie automatische Commits aus (indem Sie in Ihren DB-Einstellungen autocommit =True setzen, umständliche Namenskonvention). Dies verhindert Transaktionen für schreibgeschützte Funktionen, aber auch für Schreibfunktionen, sodass Sie diese Funktionen manuell in einen @commit_on_success-Dekorator einschließen müssen.
Alternativ fügen Sie einfach die django.middleware.transaction.TransactionMiddleware zu Ihren Middleware-Klassen hinzu. Dadurch wird jede Anfrage in eine Transaktion eingeschlossen. Dies bedeutet auch, dass schreibgeschützte Anforderungen unnötigerweise in eine Transaktion eingeschlossen werden, aber es ist eine schnelle und schmutzige Lösung.