Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

SQLite transaction stays open when its task is cancelled

Ouverte Adaptée aux débutants
#188 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

@jrderuiter y travaille déjà.

Depuis le 12/10/2026.

  • #189 par @jrderuiter — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
88/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
python, sqlite
Domaine
database

Piste de recherche

Lisez mautrix/util/async_db/aiosqlite.py, en particulier TxnConnection.transaction(), et confirmez comment l’annulation sort de son gestionnaire d’exceptions. Exécutez la reproduction fournie : annulez slow() pendant la transaction, puis démarrez une autre transaction sur la connexion. Le travail est terminé lorsque l’annulation annule la première transaction et que la deuxième transaction se termine sans l’erreur de transaction imbriquée.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
Python
Étoiles
251
Forks
85
Métriques de merge des PR
Aucune PR mergée en 30 j

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de mautrix/python

Toutes les issues de mautrix/python

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.