SQLite transaction stays open when its task is cancelled
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 88/100
Direzione di ricerca
Leggi mautrix/util/async_db/aiosqlite.py, in particolare TxnConnection.transaction(), e conferma come la cancellazione esce dal suo gestore delle eccezioni. Esegui la riproduzione fornita: annulla slow() durante la transazione, poi avvia un'altra transazione sulla connessione. Il lavoro è completato quando la cancellazione annulla la prima transazione e la seconda transazione termina senza l'errore di transazione annidata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
A cancelled task can leave an SQLite transaction open. After that, every new transaction on the connection fails with cannot start a transaction within a transaction.
Cause
TxnConnection.transaction() in mautrix/util/async_db/aiosqlite.py rolls back only on Exception:
try:
yield
except Exception:
await self.rollback()
raise
else:
await self.commit()
finally:
in_transaction.reset(token)
asyncio.CancelledError is not an Exception. When a task is cancelled inside the transaction, neither rollback() nor commit() runs. The connection goes back to the pool with the transaction still open. The next BEGIN TRANSACTION fails.
Impact
We use mautrix 0.21.1 through Hermes Agent, which keeps the Matrix crypto store in SQLite and cancels work with timeouts. After the first cancellation inside a crypto store transaction, the bot cannot share room keys, and every encrypted message fails.
Reproduce
import asyncio, os
from mautrix.util.async_db import Database
async def main():
db = Database.create("sqlite:///" + os.path.abspath("repro.db"))
await db.start()
await db.execute("CREATE TABLE IF NOT EXISTS t (x INT)")
async def slow():
async with db.acquire() as conn, conn.transaction():
await conn.execute("INSERT INTO t VALUES (1)")
await asyncio.sleep(10)
task = asyncio.create_task(slow())
await asyncio.sleep(0.2)
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
async with db.acquire() as conn, conn.transaction():
await conn.execute("INSERT INTO t VALUES (2)")
asyncio.run(main())
The last transaction fails with sqlite3.OperationalError: cannot start a transaction within a transaction.
Fix
Roll back on BaseException instead of Exception.
- Lingua principale
- Python
- Stelle
- 251
- Fork
- 85
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di mautrix/python
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
-
using inspect.unwrap on `maurix.types.Obj` places the object into a state where serializing raises a RecursionErrorForse già presa @Deln0r l’ha presa 152 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 45/100
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 30/100
Tutte le issue di mautrix/python
Issue simili
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
gradio-app/gradio#13964 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 93/100
BSData/horus-heresy-3rd-edition#3232 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
jbacalso24/mimry#123 ·
I maintainer di solito rispondono entro 1 giorno
-
p:3-mid pydanty:bug pydanty:is-working
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
pydantic/pydantic-ai#10153 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue priority: medium size: S testing
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
cubrid-lab/cubrid-cookbook-python#316 ·
I maintainer di solito rispondono entro 1 giorno