SYSADMIN JOURNAL / Linux · Networking · Security · HostingProcedure, appunti e soluzioni tecniche
Bash

Python SQLite: database is locked nelle richieste HTTP concorrenti

Pubblicato il 12/11/2026

Guida basata su un intervento sistemistico concluso e verificato. Correzione verificata di lock SQLite: transazione lasciata aperta durante richieste HTTP e scritture concorrenti. Commit mirati, timeout e test.

Errore osservato

Un servizio Python che archiviava dati da più fonti iniziava a restituire sqlite3.OperationalError: database is locked. I processi effettuavano richieste HTTP durante l'ingestione e accedevano allo stesso file SQLite, con scritture concorrenti.

La causa

Una transazione aperta manteneva il lock durante operazioni di rete potenzialmente lente. Il timeout del client era breve e la seconda scrittura scadeva prima che la prima rilasciasse il lock.

Soluzione verificata

Abbiamo spostato il commit in modo che avvenisse dopo la scrittura di ciascuna fonte, evitando di mantenere transazioni durante le richieste HTTP. Abbiamo inoltre aumentato il timeout di attesa del database da 5 a 15 secondi. I test con scrittura concorrente e l'esecuzione successiva non hanno mostrato nuovi lock.

Schema Python

import sqlite3

def save_batch(db_path, records):
    with sqlite3.connect(db_path, timeout=15) as con:
        con.execute('PRAGMA busy_timeout = 15000')
        con.executemany(
            'INSERT INTO events (source, payload) VALUES (?, ?)',
            records,
        )
        # Il context manager effettua il commit prima di uscire.

# La richiesta HTTP deve avvenire PRIMA di aprire la transazione.
payload = fetch_from_api()
save_batch('/percorso/app.db', payload)

Il codice è uno schema illustrativo, non una copia dell’applicazione. Le tabelle e le colonne devono essere adattate al proprio database.

Diagnosi e test

Misurare la durata delle transazioni e il numero di writer, controllare i timeout e riprodurre il carico con due processi indipendenti. Se si usa WAL, verificarne lo stato senza cancellare i file -wal o -shm quando il database è in uso.

Precauzioni

Aumentare soltanto il timeout spesso nasconde la causa. Per workload con numerose scritture, valutare una coda con un singolo writer o un database client-server. Prima delle modifiche conservare un backup coerente.

Risultato

Nel caso reale la revisione è stata salvata dopo backup, compilazione del codice e test concorrenti, con verifica successiva delle operazioni in produzione.

Guide correlate

I comandi con nomi segnaposto vanno adattati al proprio ambiente. Le configurazioni di produzione, gli IP e le credenziali non sono riportati.