SQLite transaction stays open when its task is cancelled
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 88/100
Línea de trabajo
Lee mautrix/util/async_db/aiosqlite.py, especialmente TxnConnection.transaction(), y confirma cómo sale la cancelación de su gestor de excepciones. Ejecuta la reproducción proporcionada: cancela slow() durante la transacción y luego inicia otra transacción en la conexión. La tarea se considera completada cuando la cancelación revierte la primera transacción y la segunda termina sin el error de transacción anidada.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Python
- Estrellas
- 251
- Forks
- 85
- Merge medio
- 1 h 53 min
- PR fusionados (30 d)
- 1
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de mautrix/python
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
-
using inspect.unwrap on `maurix.types.Obj` places the object into a state where serializing raises a RecursionErrorPosiblemente ocupada @Deln0r la tomó hace 154 días. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 45/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
Todos los issues de mautrix/python
Issues similares
-
customer-reported question
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Azure/azure-sdk-for-python#49548 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
btclib-org/btclib-wallet#409 ·
Los mantenedores suelen responder en 1 día
-
Phase 2 PSA Capability & Career Profile
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
bcgov/digital-journeys#2310 ·
-
bug good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
fastmachinelearning/hls4ml#1582 ·
Los mantenedores suelen responder en 3 días
-
Sort modelsAbiertoenhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día