SQLite – 16 – Transactions in SQLite

Transactions are a fundamental concept in SQLite and other relational databases, ensuring the integrity, consistency, and reliability of data operations. A transaction in SQLite is a sequence of one or more SQL statements that are treated as a single unit of work. Transactions provide the following key properties: Atomicity, Consistency, Isolation, and Durability (ACID). In this discussion, we will explore transactions in SQLite, their importance, commands, and practical examples.

ACID Properties:

Before diving into transactions, it’s essential to understand the ACID properties that they ensure:

  1. Atomicity: Transactions are atomic, meaning that they are treated as a single, indivisible unit of work. Either all the changes in a transaction are applied, or none of them are.
  2. Consistency: Transactions bring the database from one consistent state to another. This ensures that the database remains in a valid state even in the presence of failures.
  3. Isolation: Transactions are isolated from each other. One transaction’s changes are not visible to other transactions until the transaction is committed. This property prevents interference and ensures data integrity.
  4. Durability: Once a transaction is committed, its changes are permanent and survive system failures. Data changes are stored in a durable manner, typically on disk.

Commands for Working with Transactions:

SQLite provides commands for working with transactions:

  1. BEGIN TRANSACTION: This command starts a new transaction. You can also use BEGIN or BEGIN WORK as aliases.
  2. COMMIT: This command ends a transaction and makes all the changes made within the transaction permanent.
  3. ROLLBACK: This command undoes the changes made within the current transaction and returns the database to its state before the transaction began.

Example: Performing Transactions in SQLite

Let’s illustrate the use of transactions with a practical example. Suppose you have a SQLite database with a BankAccounts table, and you want to transfer funds between two accounts while ensuring the ACID properties of transactions.

-- Begin a transaction
BEGIN TRANSACTION;

-- Deduct $100 from Account 1
UPDATE BankAccounts
SET Balance = Balance - 100
WHERE AccountNumber = 1;

-- Add $100 to Account 2
UPDATE BankAccounts
SET Balance = Balance + 100
WHERE AccountNumber = 2;

-- Commit the transaction
COMMIT;

In this example:

  • We start a transaction using BEGIN TRANSACTION.
  • We deduct $100 from Account 1 and add $100 to Account 2 within the transaction.
  • Finally, we commit the transaction using COMMIT, making all the changes permanent.

If, for some reason, an error occurred during the transaction (e.g., a power outage), none of the changes would be applied, ensuring that the database remains in a consistent state.

Rolling Back a Transaction:

You can also roll back a transaction to undo the changes made within it. For example, let’s say you encounter an error during the funds transfer and want to reverse the transaction:

-- Begin a transaction
BEGIN TRANSACTION;

-- Deduct $100 from Account 1
UPDATE BankAccounts
SET Balance = Balance - 100
WHERE AccountNumber = 1;

-- Simulate an error
-- This could be a conditional check for some business logic error
-- In a real application, you might do something like:
-- IF some_condition THEN ROLLBACK; END IF;

-- Rollback the transaction
ROLLBACK;

In this case:

  • We start a transaction as before.
  • After deducting $100 from Account 1, we simulate an error (e.g., a business rule violation).
  • Instead of committing, we roll back the transaction using ROLLBACK, undoing any changes made within it.

Auto-Commit Mode:

By default, SQLite operates in auto-commit mode, meaning that each SQL statement is treated as a separate transaction and is automatically committed. However, you can explicitly begin and commit transactions as needed to group multiple statements into a single transaction when necessary.

Conclusion:

Transactions are a fundamental concept in SQLite and relational databases, ensuring the reliability and consistency of data operations. They provide ACID properties (Atomicity, Consistency, Isolation, and Durability) and help maintain data integrity. Understanding how to work with transactions and when to use them is crucial for developing robust and reliable database applications.