2016-08-03 25 views
3

Es ist möglich, Async-E/A mit psycopg2 (die read here sein kann) zu tun, aber ich bin mir nicht sicher, wie Async-Transaktionen zu tun. Betrachten Sie diese Abfolge der Dinge:Python Async-Transaktionen psycopg2

  • Grün Thread 1 startet die Transaktion T
  • GT1 Themen aktualisieren
  • GT2 gibt eine Transaktions Update
  • GT1 Probleme aktualisieren
  • GT1 verpflichtet Transaktion T

Ich nehme an, dass GT1 Konflikte mit GT2-Updates aktualisiert. Jetzt

nach docs:

Cursors aus der gleichen Verbindung erstellt werden nicht isoliert, das heißt, alle in der Datenbank vorgenommenen Änderungen durch einen Cursor sofort sichtbar durch die anderen Cursor.

so können wir den obigen Ablauf auf Cursor nicht implementieren. Wir könnten es auf verschiedenen Verbindungen implementieren, aber da wir async machen, kann es sein, dass (möglicherweise) tausende db-Verbindungen (nicht zu erwähnen, dass Postgres nicht so viele Out-of-the-box-Pakete verarbeiten kann) schlecht sind.

Die andere Option besteht darin, einen Pool von Verbindungen zu haben und sie wiederzuverwenden. Aber wenn wir X parallele Transaktionen ausführen, werden alle anderen grünen Threads blockiert, bis eine Verbindung verfügbar ist. Daher ist die tatsächliche Menge an nützlichen grünen Threads ~ X (unter der Annahme, dass die App stark db-gebunden ist), was die Frage aufwirft: Warum sollten wir async verwenden, um damit zu beginnen?

Jetzt kann diese Frage tatsächlich auf DB API 2.0 verallgemeinert werden. Vielleicht ist die wirkliche Antwort, dass DB API 2.0 nicht für asynchrone Programmierung geeignet ist? Wie würden wir Async auf Postgresql dann tun? Vielleicht eine andere Bibliothek?

Oder ist das vielleicht, weil das Postgresql-Protokoll tatsächlich synchron ist? Es wäre perfekt, jederzeit zu jeder Transaktion "schreiben" zu können (pro Verbindung). Postgresql müsste dafür die Transaktions-ID bereitstellen. Ist es machbar? Vielleicht ist zweiphasiges Commit die Antwort?

Oder fehlt mir hier etwas?

EDIT: Dies scheint ein allgemeines Problem mit SQL seit BEGIN; COMMIT; Semantik kann nicht einfach asynchron effizient verwendet werden.

+0

Die gleiche Verbindung wird separate Transaktionen [bei Verwendung in mehreren 'with' Statements] (http://initd.org/psycopg/docs/usage.html#with-statement) –

+0

@ClodoaldoNETo Zuerst von' with' kann nicht im Async-Modus verwendet werden. Zweitens glaube ich nicht, dass dies machbar ist, zumindest nach dieser SO-Post: http://StackOverflow.com/Questions/11620263/PostGresql-Multiple-Transactions-on-the-Same-connection Dies würde meiner Schlussfolgerung zu entsprechen 'ANFANG; COMMIT; 'Semantik.Die Frage betrifft eigentlich parallele Transaktionen. – freakish

Antwort

0

Eigentlich können Sie BEGIN verwenden; und COMMIT; mit asynchron. Was Sie brauchen, ist eine Verbindung Pool-Setup und stellen Sie sicher, dass jeder grüne Thread seine eigene Verbindung erhält (Genau wie ein echter Thread würde in einer Multithread-Anwendung).

Sie können die integrierte Transaktionsverarbeitung von psycopg2 nicht verwenden.

+0

Ja, das habe ich geschrieben. Dies ist jedoch alles andere als ideal, da Sie die Anzahl der grünen Threads effektiv auf die Poolgröße beschränken. Andere grüne Threads müssen auf eine verfügbare Verbindung warten (bei db heavy app). – freakish