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

Can't continue with a Transaction after it is commit/rollback due to mutable borrow #366

Open
darksylinc opened this issue Dec 30, 2023 · 1 comment

Comments

@darksylinc
Copy link

darksylinc commented Dec 30, 2023

Hi!

I have the following situation (dummy commands to explain the point):

    let mut tx = conn.start_transaction(TxOpts::default())?;
    tx.query_drop("SELECT 1");
    tx.commit();

    // All ok! I continue to perform operations after the transaction is committed.
    conn.query_drop("SELECT 1");

Now the problem is that I wanted to encapsulate some common functionality, so I need to pass the tx and conn variables and ended up with:

let mut tx = conn.start_transaction(TxOpts::default())?;
common_func( tx, conn ) ;


fn common_func( tx : mut Transaction, conn : mut PooledConn ) {
    tx.query_drop("SELECT 1");
    tx.commit();
    conn.query_drop("SELECT 1");
}

The problem is that this does not work because conn is already mutably borrowed in tx.

Is there a solution to this problem?

AFAIK it is not possible to reuse the Transaction tx after commit/rollback. From what I can tell, this could be solved if I could retrieve the connection again after transaction is dropped.

Something like the following would fix my problem:

let mut tx = conn.start_transaction(TxOpts::default())?;
common_func( tx ) ;


fn common_func( tx : mut Transaction ) {
    tx.query_drop("SELECT 1");
    let mut conn = tx.commit_with_connection();
    conn.query_drop("SELECT 1");
}

Is this already possible? Am I trying to do something that I shouldn't do? Is this is a simply an API oversight?

Of course rust-mysql would need to implement both commit_with_connection and rollback_with_connection.

Cheers

@blackbeam
Copy link
Owner

Hi. There is no such an API because Transaction doesn't owns the Conn, but borrows it, i.e. there is nothing to unwrap 🤷

Regarding your example - it looks really unnatural to me. It's like someone, for whatever reason, wants to write this HTML:

<div>
  <h1>Hello<h2></h1>World</h2>
</div>

Instead of writing correct HTML:

<div>
  <h1>Hello</h1><h2>World</h2>
</div>

Anyway. As mentioned in the docs, Transaction is just a convenient wrapper, so, if you really need to write it that way, then your options are:

  1. Commit tx by hand (you can also set autocommit=1):
    fn common_func( tx : mut Transaction) {
        tx.query_drop("SELECT 1");
        tx.query_drop("COMMIT");
        tx.query_drop("SELECT 1");
    }
  2. Do not use the wrapper but manage the Tx yourself using START TRANSACTION, COMMIT, ROLLBACK and other relevant directives.

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

No branches or pull requests

2 participants