fix: improve SQLite concurrency and database logging reliability
Database improvements: - Enable WAL mode for better concurrent read/write access - Add busy_timeout (30s) to wait for locked database - Add synchronous=NORMAL for balanced safety/performance - Configure check_same_thread=False for thread safety Logging improvements: - Add retry logic (3 attempts) for database locked errors - Silently skip logging on persistent failures to avoid spam - Properly rollback failed transactions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,12 +10,39 @@ This module provides classes and functions for:
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import create_engine, event
|
||||
from sqlalchemy.orm import declarative_base, sessionmaker
|
||||
|
||||
from .config import settings
|
||||
|
||||
engine = create_engine(settings.database_url)
|
||||
|
||||
def _configure_sqlite_connection(dbapi_connection, connection_record):
|
||||
"""Configure SQLite connection for better concurrency.
|
||||
|
||||
- WAL mode: Allows concurrent reads during writes
|
||||
- busy_timeout: Wait up to 30 seconds if database is locked
|
||||
- synchronous=NORMAL: Balance between safety and performance
|
||||
"""
|
||||
cursor = dbapi_connection.cursor()
|
||||
cursor.execute("PRAGMA journal_mode=WAL")
|
||||
cursor.execute("PRAGMA busy_timeout=30000")
|
||||
cursor.execute("PRAGMA synchronous=NORMAL")
|
||||
cursor.close()
|
||||
|
||||
|
||||
# Create engine with SQLite-specific configuration
|
||||
engine_kwargs = {}
|
||||
|
||||
# Add SQLite-specific settings for better concurrent access
|
||||
if settings.database_url.startswith("sqlite"):
|
||||
engine_kwargs["connect_args"] = {"check_same_thread": False}
|
||||
|
||||
engine = create_engine(settings.database_url, **engine_kwargs)
|
||||
|
||||
# Configure SQLite pragmas on connection
|
||||
if settings.database_url.startswith("sqlite"):
|
||||
event.listen(engine, "connect", _configure_sqlite_connection)
|
||||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
Reference in New Issue
Block a user