mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
Correctly ROLLBACK transaction when dropped during BEGIN. (#3980)
Previously if the transaction was dropped while the transaction was being set up it was possible that the transaction was successfully opened but not closed. In common usage this would result in returning an open transaction to the connection pool which would have unexpected effects ranging from errors due to trying to nest transaction or serious bugs such as intended changes not occurring as they were unexpectedly inside a transaction that would never commit. This resolves the issue by constructing the `Transaction` object (which activates the drop handler) before starting to open the transaction. In the worst case this could result in trying to `ROLLBACK` a transaction that was never started but this just results in a harmless error which is much better than leaving an unexpected open transaction active on the connection. Fixes: https://github.com/launchbadge/sqlx/issues/3932
This commit is contained in:
parent
a096548221
commit
ce878ce874
@ -100,15 +100,19 @@ where
|
||||
conn: impl Into<MaybePoolConnection<'c, DB>>,
|
||||
statement: Option<SqlStr>,
|
||||
) -> BoxFuture<'c, Result<Self, Error>> {
|
||||
let mut conn = conn.into();
|
||||
let conn = conn.into();
|
||||
|
||||
Box::pin(async move {
|
||||
DB::TransactionManager::begin(&mut conn, statement).await?;
|
||||
|
||||
Ok(Self {
|
||||
let mut tx = Self {
|
||||
connection: conn,
|
||||
|
||||
// If the call to `begin` fails or doesn't complete we want to attempt a rollback in case the transaction was started.
|
||||
open: true,
|
||||
})
|
||||
};
|
||||
|
||||
DB::TransactionManager::begin(&mut tx.connection, statement).await?;
|
||||
|
||||
Ok(tx)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user