← Tous les exercices
Un lot atomique : COMMIT ou ROLLBACK
Partie 4 · ★★★
Un traitement en lot doit être tout ou rien : si une annonce du lot est invalide, tout le lot est annulé. Le journal technique doit garder la trace de l'erreur : on l'écrit après le ROLLBACK, sinon l'écriture du log serait elle aussi annulée.
Complète traiter_lot : BEGIN au départ, COMMIT si tout passe, ROLLBACK en cas d'erreur (la table a une contrainte CHECK (budget >= 0)). La fonction renvoie True si le lot est validé.
import sqlite3 con = sqlite3.connect(":memory:", isolation_level=None) con.executescript(""" CREATE TABLE marche(id INTEGER PRIMARY KEY, titre TEXT NOT NULL, budget REAL CHECK (budget >= 0)); CREATE TABLE log_technique(id INTEGER PRIMARY KEY, niveau TEXT, message TEXT); """) def traiter_lot(lot): con.execute("___") try: for titre, budget in lot: con.execute("INSERT INTO marche(titre, budget) VALUES (?, ?)", (titre, budget)) con.execute("___") except sqlite3.DatabaseError as e: con.execute("___") con.execute("INSERT INTO log_technique(niveau, message) VALUES ('ERROR', ?)", (str(e),)) return False con.execute("INSERT INTO log_technique(niveau, message) VALUES ('INFO', 'lot ok')") return True res_bad = traiter_lot([("A", 10), ("B", -5), ("C", 20)]) n_apres_echec = con.execute("SELECT COUNT(*) FROM marche").fetchone()[0] res_ok = traiter_lot([("D", 5), ("E", 6)]) n_apres_succes = con.execute("SELECT COUNT(*) FROM marche").fetchone()[0] niveaux = [r[0] for r in con.execute("SELECT niveau FROM log_technique ORDER BY id")]
Ctrl/⌘+Entrée