tursodatabase/turso · error
COMMIT must end the transaction
Error message
COMMIT must end the transaction
What it means
After issuing COMMIT on each session, the batch runner asserts the connection is back in autocommit mode. If is_autocommit() is still false after commit(), the transaction did not actually end, invalidating the measurement and possibly leaving the connection in a broken state, so the benchmark aborts.
Source
Thrown at perf/memory/src/fts.rs:217
JournalMode::Wal => "BEGIN",
JournalMode::Mvcc => "BEGIN CONCURRENT",
};
for session in &self.sessions {
session.begin(begin).await?;
}
for session in &self.sessions {
active += usize::from(!session.conn.is_autocommit()?);
}
ensure!(
active == self.sessions.len(),
"transactions must overlap before queries start"
);
}
let mut result = self.query_all(queries).await?;
if transactions {
for session in &self.sessions {
session.commit().await?;
ensure!(
session.conn.is_autocommit()?,
"COMMIT must end the transaction"
);
}
result.transactions = self.sessions.len();
result.max_active_transactions = active;
}
Ok(result)
}
.await;
if outcome.is_err() {
for session in &self.sessions {
if !session.conn.is_autocommit()? {
session.conn.execute("ROLLBACK", ()).await?;
}
}
}
outcomeView on GitHub (pinned to 492c4a71cd)
Solutions
- Log is_autocommit() before and after commit() on each session to isolate the connection that fails to end its transaction
- Check the query_all() results for errors that may have aborted the commit path
- Verify the driver version handles COMMIT correctly; recreate the session if state is corrupted
Defensive patterns
Strategy: validation
Validate before calling
session.commit().await?;
if !session.conn.is_autocommit()? {
return Err(anyhow!("session still in transaction after COMMIT"));
} Try / catch
if let Err(e) = batch.run().await {
if e.to_string().contains("COMMIT must end") {
// force rollback / recreate session before continuing
}
} Prevention
- Check for errors in queries inside the transaction before committing
- Avoid nested transaction attempts on a single connection
- Recreate sessions that survive an earlier error
When it happens
Trigger: Calling session.commit() during a transactional batch when COMMIT is ignored, fails silently, or the connection starts a new implicit transaction immediately, leaving is_autocommit() false.
Common situations: Driver-level commit bug; nested/deferred transactions that don't fully release on COMMIT; a statement inside the transaction opened a new transaction after commit; connection in a broken state after an earlier query error.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- transactions must overlap before queries start
- Unexpected row for INSERT
- Savepoints are not supported by Turso
- Unexpected row for CREATE TABLE
- Command was not prepared.
AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-09-13).
Data as JSON: /api/errors/1a40da9dc5204498.
Report an issue: GitHub.