SQLite transaction stays open when its task is cancelled
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 88/100
Rechercherichtung
Lies mautrix/util/async_db/aiosqlite.py, insbesondere TxnConnection.transaction(), und bestätige, wie die Cancellation den Exception-Handler verlässt. Führe die bereitgestellte Reproduktion aus: Brich slow() während der Transaktion ab und starte dann eine weitere Transaktion auf der Verbindung. Erledigt ist die Aufgabe, wenn die Cancellation die erste Transaktion zurückrollt und die zweite Transaktion ohne den Fehler wegen verschachtelter Transaktionen abgeschlossen wird.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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.
- Vorherrschende Sprache
- Python
- Sterne
- 251
- Forks
- 85
- Ø Merge
- 1 Std. 53 Min.
- Gemergte PRs (30 T.)
- 1
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus mautrix/python
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 30/100
-
using inspect.unwrap on `maurix.types.Obj` places the object into a state where serializing raises a RecursionErrorEvtl. vergeben @Deln0r hat das vor 154 Tagen übernommen. Offenbug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 45/100
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 25/100
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 30/100
Ähnliche Issues
-
vis.image() reports "Unsupported number of image channels: 224" for an HxWxC imageEvtl. vergeben @piyush182004 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
fossasia/visdom#1997 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 6 Tagen
-
Byse new domainOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
Gujal00/ResolveURL#1525 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Serialisation fails with pydantic 2.14: wrap serialisers pass SerializationInfo as index_keyEvtl. vergeben @hugohills-regnosys hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
finos/rune-python-runtime#45 ·
-
[Bug]: LangGraph Store sync put bypasses namespace validationEvtl. vergeben @ktz03 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
volcengine/OpenViking#6050 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
hummingbot/condor#283 ·
Maintainer antworten meist innerhalb von 1 Tag