Contents / Previous / Next


Transactions, Isolation and Locks

A DB allows users to view and modify information simultaneously and ensure data integrity.

Every SQL query is executed in a transaction. Transactions give databases an all-or-nothing capability when making modifications.

Commands controling transaction and database access are the subset of SQL called the Data Control Language (DCL).

Example: Suppose you were executing a query to add $500 to everyone's salary and accidentally kicked the power cord out of the wall during the update procedure. Without transactions, the query may have updated half the salaries, but not the rest. It would be difficult to know where the UPDATE stopped.
With transactions, you can check to see if any of the rows were updated. If one was updated, then all were updated. If not, you can simply re-execute the query.


Multi-statement Transactions

With BEGIN...COMMIT you can bind multiple statements into a single transaction. Either all statements are executed to completion or none has any effect.

Example:
Suppose you have a table of bank account balances, and you wish to transfer $100 from one account to another account:

BEGIN work; UPDATE bankacct SET balance = balance - 100 WHERE acctno = '82021'; UPDATE bankacct SET balance = balance + 100 WHERE acctno = '96814'; COMMIT work; The multi-statement transaction guarantee that the UPDATEs are either both completed or have no effect.

A group of statements surrounded by BEGIN and COMMIT is called a transaction block.

atomic updates: Being atomic is an important property of updates, each update is implicity inclosed into a transaction.


ROLLBACK

When you begin a transaction with BEGIN, you do not have to commit it using COMMIT. Instead, you can close the transaction with ROLLBACK and the transaction will be discarded. The database is left as though the transaction had never been executed. Example: BEGIN work ; DELETE FROM assign WHERE stud=1; ROLLBACK work ; The "work" transaction is rolled back, causing the DELETE to have no effect.

Likewise, if any query inside a multistatement transaction cannot be executed due to an error, the entire transaction is automatically rolled back.


Visibility of Transactions

When multiple transactions are running concurrently, each one should not be able to see the incomplete changes made by others.
Per default only committed transactions are visible to users. Although the current user sees his changes, other users do not see them until the transaction is committed.


Transaction Isolation

Each transaction is isolated from other active transactions. But there are different levels of isolation.

The isolation level discussed so far is called SERIALIZABLE isolation.
SERIALIZABLE isolation forces the database to execute all transactions as though they were run serially (one after another), even if they are run concurrently.
SERIALIZABLE isolation provides a stable view of the database for SELECT transactions.
For transactions containing UPDATE and DELETE queries, if two concurrent transactions attempt to UPDATE the same row, serializability is impossible. In such a case, PostgreSQL forces one transaction to roll back.

ANSI/ISO SQL standard levels of transaction isolation:

SERIALIZABLE
The current transaction can only see rows committed before first query or data-modification statement was executed in this transaction.

Repeatable read
It is not possible that a transaction re-reads data it has previously read and finds that data has been modified by another transaction (that committed since the initial read).

READ COMMITTED
A transaction re-reads data that has been modified and commited by another transaction.

Read Uncommitted (dirty reads are possible)
A transaction reads data written by concurrent uncommitted transaction.
PostgreSQL offers the READ COMMITTED and SERIALIZABLE isolation levels.


Locks

Exclusive locks prevent other users from modifying a row or an entire table until the current transaction is either committed or rolled back.

Rows modified by UPDATE and DELETE are then exclusively locked automatically for the duration of the transaction.

You can use SELECT...FOR UPDATE to lock selected rows (on which you want to base an update) until the end of the current transaction. Example:

BEGIN ; SELECT * FROM stud WHERE name='john' FOR UPDATE ; id | name | semester | diploma | gender ----+------+----------+---------+-------- 4 | john | 3 | phy | m (1 row) UPDATE stud SET name='john-boy' WHERE name='john' ; COMMIT ; Another user cannot modify the John's row between the SELECT...FOR UPDATE and UPDATE. In fact, the row remains locked until the transaction ends.


LOCK -- explicitly lock a table

You can also manually lock tables until the end of a transaction: LOCK [ TABLE ] name [, ...] LOCK [ TABLE ] name [, ...] IN lockmode MODE where lockmode is one of: ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE SHARE MODE protects a table against concurrent data updates.

Example:

BEGIN WORK; LOCK TABLE stud IN SHARE MODE; . . COMMIT WORK;