Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transactions support #79

Open
jeromegn opened this issue Apr 18, 2023 · 3 comments
Open

Transactions support #79

jeromegn opened this issue Apr 18, 2023 · 3 comments
Labels
enhancement New feature or request

Comments

@jeromegn
Copy link

I noticed transactions are not supported, at least when testing with tokio-postgres.

My pgwire handler receives a BEGIN statement and it's handled by the SimpleQueryHandler implementation. Then the single statement I have in the transaction is handled by the ExtendedQueryHandler. When I finally get to tx.commit().await, there's no transaction to commit because all of these things are disconnected.

Is there a way to handle transactions? I figure it might be possible by keeping a record when we get a BEGIN and somehow associate it with the incoming connection and sharing that information between the simple and extended query handler. It seemed like a lot of work though.

Example test code:

        let (mut pg, connection) = tokio_postgres::connect(
            format!("host={} port={}", pg_addr.ip(), pg_addr.port()).as_str(),
            NoTls,
        )
        .await?;

        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("connection error: {e}");
            }
        });

        let rows = {
            let tx = pg.transaction().await?;
            let rows = tx.query("SELECT * FROM sqlite_master;", &[]).await?;
            tx.commit().await?;
            rows
        };
@sunng87
Copy link
Owner

sunng87 commented Apr 18, 2023

At the moment, pgwire only parses the wire protocol and developer has to implement those sql commands sent over the protocol.

You can create a struct that implement both SimpleQueryHandler and ExtendedQueryHandler so they can share the state of transaction.

I might add an additional helper layer on top of current API layer for transaction support in future.

@sunng87 sunng87 added dependencies Pull requests that update a dependency file enhancement New feature or request and removed dependencies Pull requests that update a dependency file labels Apr 18, 2023
@tmokmss
Copy link

tmokmss commented Dec 27, 2023

Hi @sunng87 I also encountered a similar issue while trying to implement a server with transaction support and have a question.

In a transaction, a processor must process e.g. 1. BEGIN, 2. UPDATE xxx, and 3. COMMIT queries in different do_query executions. So now how can I determine that the 2nd query is associated with 1st query, and 3rd query is associated with 2nd query?

I expected something like connection ID to associate those queries but I couldn't find any. Is it currently impossible?

@sunng87
Copy link
Owner

sunng87 commented Dec 28, 2023

I think you can use socket address for connection, it can be fetched from ClientInfo, the second argument of handlers.

Also there is a metadata hashmap in ClientInfo can be used to stored some data associated with the client and be dropped when client disconnected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants