Replies: 4 comments 8 replies
-
|
@edgedb/engineering |
Beta Was this translation helpful? Give feedback.
-
This part is necessary for proper backend connection pooling in any case, where each connection will maintain its own prepared statement cache.
I'm having trouble reconciling these two points. In my mind, it's the opposite: we must make sure that, outside of an explicit EdgeQL transaction, we always send |
Beta Was this translation helpful? Give feedback.
-
|
This sounds like if we're getting error we should send [sync] and wait for response. I think that sending [execute][sync] always may be more useful anyway. Note that error response can be on the hot path, in a case like this: (not every such use case can be covered by |
Beta Was this translation helpful? Give feedback.
-
|
The problem with non starting implicit transaction on Prepare is: what if schema changed between Prepare and Execute, and query is still valid but descriptor is not? E.g. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This will likely be merged into the ports RFC.
Preface
As of EdgeDB 1.0 Alpha 6, its binary protocol has the
[SYNC]message, which mimics the semantics of the[SYNC]message in PostgreSQL binary protocol.Here's an excerpt from the PostgreSQL documentation:
Basically, any command after the last
[SYNC]opens a new implicit transaction. Any commands issued after that will be run in that transaction, until another[SYNC]message commits it. For example, let's consider the following sequence of client protocol messages:[...][SYNC], and then after some time:[EXECUTE query="INSERT Foo ..."][EXECUTE query="START TRANSACTION"][EXECUTE query="INSERT Bar ..."][EXECUTE query="ROLLBACK"][SYNC]Perhaps surprisingly, both
INSERT Foo ...andINSERT Bar ...statements will be rollbacked. This happens because at (3), the PostgreSQL server would start a new transaction and run (3) in it. Later, (4) would be basically meaningless (unless it specifies isolation level), as the transaction has already been started. Then (6) would cancel the transaction as well as the effects of (3) and (5).The design of
Syncmakes sense for PostgreSQL protocol. It allows fine-grained control over the DB connection state. In EdgeDB, especially with the new ports RFC soon to be implemented,[SYNC]poses some challenges:The implicit transactions semantics means that EdgeDB client connections will have to be pinned to backend PostgreSQL connections until the implicit transaction is closed. Consider the very basic example of a client sending
[PREPARE]and waiting for the server to reply; once the response is received, the client would send[EXECUTE]and then[SYNC]. The implicit transaction would be open between receiving[PREPARE]and the final[SYNC]. Therefore, we will have to reserve a backend PostgreSQL connection exclusively for this EdgeDB client.EdgeDB client libraries that fail to implement
[SYNC]properly will quickly exhaust server backend connections.Proposal
The proposal boils down to the following few adjustments:
EdgeDB protocol will not support implicit transactions. Transactions will have to be open explicitly with EdgeQL.
The
[SYNC]message will stay and will be used by clients to:Sync.[PREPARE]will become lazy w.r.t. actually preparing a statement in PostgreSQL. With the new semantics,[PREPARE]will parse and compile the EdgeQL query, returning type descriptors (or an error) to the client and caching the compiled SQL. The SQL code will actually be prepared in PostgreSQL when EdgeDB receives an[EXECUTE]message.EdgeDB server will no longer always relay
[SYNC]messages to PostgreSQL.Backwards Compatibility
The existing drivers should continue working unless they rely on implicit transactions. To the best of my knowledge, our Python/JS/Rust drivers do not rely on them.
What if we want PostgreSQL semantics one day?
We can add a new protocol message to control transactions explicitly. Although it's currently unclear what kind of use cases would require that.
Beta Was this translation helpful? Give feedback.
All reactions