Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

SQLite transaction stays open when its task is cancelled

Cerrado Apto para principiantes
#188 0 comentarios 0 reacciones 0 asignados Ver en GitHub

@jrderuiter ya está trabajando en esto.

Desde el 12/10/2026.

  • #189 de @jrderuiter — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
88/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python, sqlite
Área
database

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

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de mautrix/python

Todos los issues de mautrix/python

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.