SERIALIZABLE isolation level

Transactions and Error Handling in SQL Server

Miriam Antona

Software Engineer

SERIALIZABLE

  • Most restrictive isolation level
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
Transactions and Error Handling in SQL Server

Isolation level comparison

Dirty reads Non-repeatable reads Phantom reads
READ UNCOMMITTED yes yes yes
READ COMMITTED no yes yes
REPEATABLE READ no no yes
SERIALIZABLE no no no
Transactions and Error Handling in SQL Server

Locking records with SERIALIZABLE

  • Query with WHERE clause based on an index range -> Locks only that records
  • Query not based on an index range -> Locks the complete table
Transactions and Error Handling in SQL Server

SERIALIZABLE - query based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
    SELECT * FROM customers
    WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------|-----|-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |

Locked record

Transactions and Error Handling in SQL Server

SERIALIZABLE - query based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
    SELECT * FROM customers
    WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------|-----|-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |

Locked record

Transaction 2

...

...

INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);

Has to wait!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
    SELECT * FROM customers 
    WHERE customer_id BETWEEN 1 AND 3;

    SELECT * FROM customers 
    WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------|-----|-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |

Transaction 2

...

...

INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);

Has to wait!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
    SELECT * FROM customers 
    WHERE customer_id BETWEEN 1 AND 3;

    SELECT * FROM customers 
    WHERE customer_id BETWEEN 1 AND 3;
COMMIT TRAN

Transaction 2

...

...

INSERT INTO customers (customer_id, first_name, ...)
VALUES (2, 'Phantom', 'Ph', '[email protected]', 555666222);

Finally executed!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
    SELECT * FROM customers 
    WHERE customer_id BETWEEN 1 AND 3;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------|-----|-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |

Transaction 2

...

...

INSERT INTO customers (customer_id, first_name, ...)
VALUES (200, 'Phantom', 'Ph', '[email protected]', 555666222);

Instantly inserted!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query not based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
    SELECT * FROM customers;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------| ... |-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |
...
| 10          | Carol      | York      | ... | 555148988 |

Locks the complete table

Transaction 2

...

...

INSERT INTO customers
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);

Has to wait!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query not based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
    SELECT * FROM customers;

    SELECT * FROM customers;
| customer_id | first_name | last_name | ... | phone     |
|-------------|------------|-----------| ... |-----------|
| 1           | Dylan      | Smith     | ... | 555888999 |
...
| 10          | Carol      | York      | ... | 555148988 |

Transaction 2

...

...

INSERT INTO customers
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);

Has to wait!

Transactions and Error Handling in SQL Server

SERIALIZABLE - query not based on an index range

Transaction 1

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
    SELECT * FROM customers;

    SELECT * FROM customers;
COMMIT TRAN

Transaction 2

...

...

INSERT INTO customers 
VALUES (100, 'Phantom', 'Ph', '[email protected]', 555666222);

Finally executed!

Transactions and Error Handling in SQL Server

SERIALIZABLE - summary

Pros:

  • Good data consistency: Prevents dirty, non-repeatable and phantom reads

Cons:

  • You can be blocked by a SERIALIZABLE transaction

When to use it?:

  • When data consistency is a must
Transactions and Error Handling in SQL Server

Let's practice!

Transactions and Error Handling in SQL Server

Preparing Video For Download...