SQLite transaction stays open when its task is cancelled
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 88/100
Hướng nghiên cứu
Đọc mautrix/util/async_db/aiosqlite.py, đặc biệt là TxnConnection.transaction(), và xác nhận cách việc hủy thoát khỏi trình xử lý ngoại lệ. Chạy quy trình tái hiện được cung cấp: hủy slow() trong khi giao dịch đang diễn ra, sau đó bắt đầu một giao dịch khác trên kết nối. Hoàn tất khi việc hủy rollback giao dịch đầu tiên và giao dịch thứ hai hoàn thành mà không gặp lỗi giao dịch lồng nhau.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Python
- Star
- 251
- Fork
- 85
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của mautrix/python
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
-
using inspect.unwrap on `maurix.types.Obj` places the object into a state where serializing raises a RecursionErrorCó thể đã có người làm @Deln0r đã nhận 153 ngày trước. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 45/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 30/100
Tất cả issue của mautrix/python
Issue tương tự
-
area: agents area: docs good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
openapi/gknowledge#23 ·
-
get() for StrEnumCó thể đã có người làm @FeJo5952 đã nhận hôm nay. Đang mởgood first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
collective/icalendar#1921 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Improvement Python Spans
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
getsentry/sentry-python#7994 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
alphagov/notifications-api#5004 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
equinor/radix-flux#3922 ·
Maintainer thường phản hồi trong vòng 1 ngày