Ce face BEGIN, COMMIT, ROLLBACK
Fără BEGIN, SQLite pune fiecare instrucțiune în propria tranzacție și o salvează imediat (modul autocommit). Cu BEGIN deschizi o tranzacție: modificările se văd în conexiunea ta, dar ajung definitiv în fișier doar la COMMIT. ROLLBACK le anulează pe toate.
Tipul tranzacției contează când mai multe programe folosesc aceeași bază. DEFERRED (implicit) nu blochează nimic până la prima citire sau scriere. IMMEDIATE ia imediat dreptul de scriere, așa că o eroare database is locked apare la BEGIN, nu la jumătatea lucrului; este alegerea potrivită când știi că vei scrie. EXCLUSIVE blochează și cititorii (în afară de modul WAL, unde se comportă ca IMMEDIATE).
Tranzacțiile fac și inserările mult mai rapide: în autocommit, fiecare INSERT așteaptă scrierea pe disc; într-o tranzacție, scrierea pe disc se face o dată, la COMMIT. Tranzacțiile nu se pot imbrica cu BEGIN; pentru niveluri interioare există SAVEPOINT.
Parametri
| Parametru | Descriere |
|---|---|
DEFERRED |
Implicit: blocările se iau abia la prima citire sau scriere. |
IMMEDIATE |
Ia imediat dreptul de scriere; alți scriitori așteaptă sau primesc SQLITE_BUSY. |
EXCLUSIVE |
Ca IMMEDIATE, dar în modurile non-WAL blochează și cititorii din alte conexiuni. |
Exemple
Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.
CREATE TABLE conturi (
titular TEXT PRIMARY KEY,
sold INTEGER NOT NULL CHECK (sold >= 0)
);
INSERT INTO conturi VALUES ('Ana', 500), ('Mihai', 100);
Exemplul 1: Un transfer între conturi
Cele două UPDATE-uri trebuie să reușească împreună. Cu BEGIN IMMEDIATE ... COMMIT, nimeni nu vede o stare intermediară în care banii au plecat de la Ana, dar n-au ajuns la Mihai.
BEGIN IMMEDIATE;
UPDATE conturi SET sold = sold - 200 WHERE titular = 'Ana';
UPDATE conturi SET sold = sold + 200 WHERE titular = 'Mihai';
COMMIT;
SELECT * FROM conturi ORDER BY titular;
Rezultat
╭─────────┬──────╮
│ titular │ sold │
╞═════════╪══════╡
│ Ana │ 300 │
│ Mihai │ 300 │
╰─────────┴──────╯
Exemplul 2: ROLLBACK anulează tot
În interiorul tranzacției, ștergerea se vede. După ROLLBACK, rândurile sunt înapoi.
BEGIN;
DELETE FROM conturi;
SELECT count(*) AS conturi_in_tranzactie FROM conturi;
ROLLBACK;
SELECT count(*) AS conturi_dupa_rollback FROM conturi;
Rezultat
╭───────────────────────╮
│ conturi_in_tranzactie │
╞═══════════════════════╡
│ 0 │
╰───────────────────────╯
╭───────────────────────╮
│ conturi_dupa_rollback │
╞═══════════════════════╡
│ 2 │
╰───────────────────────╯
Exemplul 3: BEGIN în interiorul altei tranzacții
Tranzacțiile nu se imbrică. Al doilea BEGIN dă eroare; folosește SAVEPOINT.
BEGIN;
UPDATE conturi SET sold = sold - 50 WHERE titular = 'Ana';
BEGIN;
Rezultat (eroare)
Error near line 3: cannot start a transaction within a transaction
Greșeli frecvente
- Inserezi mii de rânduri fără tranzacție. Fiecare
INSERTașteaptă discul; pune-le întreBEGINșiCOMMITși durează de zeci de ori mai puțin. - Începi cu
BEGIN(deferred), citești, apoi încerci să scrii în timp ce altă conexiune scrie: primeștidatabase is lockedla jumătatea tranzacției. Dacă știi că vei scrie, începe cuBEGIN IMMEDIATE. - Crezi că o eroare dintr-o instrucțiune anulează automat toată tranzacția. De obicei se anulează doar instrucțiunea care a eșuat, iar tranzacția rămâne deschisă: tu decizi dacă dai
ROLLBACKsauCOMMIT.
Comenzi înrudite
SAVEPOINT: Pune un punct de revenire în interiorul unei tranzacții: poți anula doar modificările de după el, fără să pierzi tot.PRAGMA journal_mode (WAL): Alege cum protejează SQLite datele la scriere. Modul WAL permite citiri în timp ce altcineva scrie și este alegerea uzuală pentru aplicații.PRAGMA foreign_keys: Pornește verificarea cheilor străine. În SQLite este oprită implicit și trebuie pornită la fiecare conexiune.SQLite din Python (sqlite3): Modulul sqlite3 din biblioteca standard Python: conectare, interogări cu parametri, tranzacții și rânduri ca dicționare.
Întrebări & Exemple de Cod:
BEGIN, COMMIT, ROLLBACKAi o nelămurire despre utilizarea comenzii
BEGIN, COMMIT, ROLLBACKsau ai descoperit un truc / fragment de cod util? Distribuie-l cu ceilalți programatori!Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!
Nu au fost adăugate încă întrebări sau exemple de cod pentru această pagină. Dacă ai întâlnit o problemă sau ai un snippet util, adaugă-l mai jos pentru a-i ajuta pe ceilalți.