Presentation is loading. Please wait.

Presentation is loading. Please wait.

SQL – Transactions in SQLite

Similar presentations


Presentation on theme: "SQL – Transactions in SQLite"— Presentation transcript:

1 SQL – Transactions in SQLite

2 Transaction Lifecycle
It starts with a BEGIN statement (which defines the type of transaction). Then, there are the statements within the transaction. The transaction can end a few ways: With a COMMIT statement (indicating that the database modifications should be made permanent) With a ROLLBACK statement (indicating an abort of the transaction and undoing of its effects) With an error (which achieves the same effect as ROLLBACK) We'll discuss ROLLBACK later in the class.

3 BEGIN and COMMIT You start a new transaction with "BEGIN TRANSACTION;". You finish a transaction with "COMMIT TRANSACTION;". BEGIN TRANSACTION; INSERT INTO students VALUES ('Josh', 3.5); UPDATE students SET grade = grade + 0.5; COMMIT TRANSACTION;

4 Auto commit and Python - SQLite
By default, SQLite auto commits after every statement. This means that outside of an explicit transaction, every statement is its own transaction. When you specify "BEGIN TRANSACTION", auto commit turns off until you say "COMMIT TRANSACTION" (or "ROLLBACK TRANSACTION"). The python-SQLite module tries to be helpful by adding "BEGINs" and "COMMITs" for you. We want to turn this behavior off by setting isolation_level to None (See next slide). Python-sqlite3 module also has commit (and rollback) methods on it's Connection objects. DO NOT USE THEM! They don't play nicely with explicit "BEGIN" and "COMMIT" (and "ROLLBACK").

5 import sqlite3 con1 = sqlite3.connect("test.db", isolation_level=None) con2 = sqlite3.connect("test.db", isolation_level=None) con1.execute("DROP TABLE IF EXISTS students;") con1.execute("CREATE TABLE students (name TEXT);") con1.execute("INSERT INTO students VALUES ('Grant');") con1.execute("BEGIN TRANSACTION;") con1.execute("INSERT INTO students VALUES ('Josh');") con2.execute("BEGIN TRANSACTION;") res = con2.execute("SELECT * FROM STUDENTS;") print("con2:",list(res)) # con2: [('Grant',)] res = con1.execute("SELECT * FROM STUDENTS;") print("con1:", list(res)) # con1: [('Grant',), ('Josh',)] con2.execute("COMMIT TRANSACTION;") con1.execute("COMMIT TRANSACTION;")

6 Normal usage In the previous example, one thread (one python script) had two connections to the same database. In normal usage, different people/programs would be talking to the same database. Because SQLite uses locking to ensure serializability, it can't commit database modifications until it holds the exclusive lock. But it our case, the next python command can't run until the previous command finished. So if the previous command is waiting for a lock to be released, it will wait forever. (or until the default timeout length of 5 seconds passes) Normally, transactions will take less than a second to run, so lock out isn't a very big issue.

7 Database element should SQLite use to lock with?
Value Row Table Database

8 Five states of locking the database
UNLOCKED No locks are held on the database. The database may be neither read nor written. Any internally cached data is considered suspect and subject to verification against the database file before being used. Other processes can read or write the database as their own locking states permit. This is the default state. SHARED The database may be read but not written. Any number of processes can hold SHARED locks at the same time, hence there can be many simultaneous readers. But no other thread or process is allowed to write to the database file while one or more SHARED locks are active. RESERVED A RESERVED lock means that the process is planning on writing to the database file at some point in the future but that it is currently just reading from the file. Only a single RESERVED lock may be active at one time, though multiple SHARED locks can coexist with a single RESERVED lock. RESERVED differs from PENDING in that new SHARED locks can be acquired while there is a RESERVED lock.

9 Five states of locking the database
PENDING A PENDING lock means that the process holding the lock wants to write to the database as soon as possible and is just waiting on all current SHARED locks to clear so that it can get an EXCLUSIVE lock. No new SHARED locks are permitted against the database if a PENDING lock is active, though existing SHARED locks are allowed to continue. EXCLUSIVE An EXCLUSIVE lock is needed in order to write to the database file. Only one EXCLUSIVE lock is allowed on the file and no other locks of any kind are allowed to coexist with an EXCLUSIVE lock. In order to maximize concurrency, SQLite works to minimize the amount of time that EXCLUSIVE locks are held.

10 SQlite's Three Transaction Modes
The default mode (and the mode I've been demonstrating) is called DEFERRED. It requests a shared lock the first time it tries to read It requests an exclusive lock the first time it tries to write IMMEDIATE transaction mode: It requests a RESERVED lock immediately (during the "BEGIN" command) It will fail/wait if another transaction is holding an exclusive lock It requests an exclusive lock prior to writing On commit, the reserved lock is promoted to an exclusive lock EXCLUSIVE transaction mode: It requests an exclusive lock immediately It will fail/wait if another transaction is holding a shared or exclusive lock All transactions release their all their locks when committing

11 Specifying a transaction mode
BEGIN TRANSACTION; -- Defaults to DEFERRED BEGIN DEFERRED TRANSACTION; -- Same as above BEGIN IMMEDIATE TRANSACTION; -- Starts in immediate mode BEGIN EXCLUSIVE TRANSACTION; -- Starts in exclusive mode COMMIT TRANSACTION; -- Commits regardless of transaction mode ROLLBACK TRANSACTION; -- Rollback regardless of transaction mode

12 Which is the best transaction mode?
Default Deferred Immediate Exclusive


Download ppt "SQL – Transactions in SQLite"

Similar presentations


Ads by Google