Added async lock to database transactions to prevent concurrent transaction conflicts.
CI / Formatting (push) Successful in 5s
CI / Linting (push) Successful in 4s
CI / Tests (push) Successful in 22s
CI / Type Checking (push) Successful in 11s
CI / Spelling (push) Successful in 5s

This commit is contained in:
2026-03-23 09:49:44 -04:00
parent 53b8bd3fae
commit ca3011011a
+5 -1
View File
@@ -14,6 +14,7 @@
"""Async SQLite database access for Crabstero's persistent storage.""" """Async SQLite database access for Crabstero's persistent storage."""
import asyncio
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from typing import TYPE_CHECKING, NamedTuple, Self from typing import TYPE_CHECKING, NamedTuple, Self
@@ -109,13 +110,16 @@ class Database:
:param connection: An open aiosqlite connection. :param connection: An open aiosqlite connection.
""" """
self._connection = connection self._connection = connection
self._tx_lock = asyncio.Lock()
@asynccontextmanager @asynccontextmanager
async def _transaction(self) -> AsyncIterator[None]: async def _transaction(self) -> AsyncIterator[None]:
"""Begin an immediate write transaction. """Begin an immediate write transaction.
Commits on success, rolls back on error. Acquires an async lock so that only one transaction runs at a
time, then commits on success or rolls back on error.
""" """
async with self._tx_lock:
await self._connection.execute("BEGIN IMMEDIATE") await self._connection.execute("BEGIN IMMEDIATE")
try: try:
yield yield