SQLite transaction stays open when its task is cancelled
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 88/100
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
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de mautrix/python
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 30/100
-
using inspect.unwrap on `maurix.types.Obj` places the object into a state where serializing raises a RecursionErrorPeut-être pris @Deln0r l’a pris il y a 152 jours. Ouvertebug
Difficulté 2/5 1-3 heures Accessibilité débutants 45/100
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 25/100
-
Difficulté 4/5 3-5 jours Accessibilité débutants 30/100
Toutes les issues de mautrix/python
Issues similaires
-
Difficulté 1/5 1-3 heures Accessibilité débutants 88/100
gradio-app/gradio#13964 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 93/100
BSData/horus-heresy-3rd-edition#3232 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
jbacalso24/mimry#123 ·
Les mainteneurs répondent en général sous 1 jour
-
p:3-mid pydanty:bug pydanty:is-working
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
pydantic/pydantic-ai#10153 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
good first issue priority: medium size: S testing
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
cubrid-lab/cubrid-cookbook-python#316 ·
Les mainteneurs répondent en général sous 1 jour