Ok, myślę, że to rozgryzłem. Problem tkwi w długotrwałym problemie z Django i Psycopg2. Zasadniczo Psycopg2 automatycznie wyda instrukcję BEGIN do DB. Jeśli jednak Django uzna, że nie nastąpiła modyfikacja danych, nie wyda COMMIT na koniec transakcji.
Istnieje kilka rozwiązań tego problemu, spójrz na http://www. slideshare.net/OReillyOSCON/unbreaking-your-django-application po więcej szczegółów. W idealnym przypadku wyłączysz automatyczne zatwierdzenia (ustawiając autocommit =True w ustawieniach bazy danych, niezręczną konwencję nazewnictwa). Zapobiega to transakcjom na funkcjach tylko do odczytu, ale także na funkcjach zapisu, więc musisz ręcznie zawinąć te funkcje w dekorator @commit_on_success.
Alternatywnie wystarczy dodać django.middleware.transaction.TransactionMiddleware do klas oprogramowania pośredniczącego. Spowoduje to uwzględnienie każdego żądania w transakcji. Oznacza to również niepotrzebne pakowanie żądań tylko do odczytu w transakcję, ale jest to szybkie i brudne rozwiązanie.