Рівень ізоляції SERIALIZABLE

Транзакції та обробка помилок у SQL Server

Miriam Antona

Software Engineer

SERIALIZABLE

  • Найбільш обмежувальний рівень ізоляції
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
Транзакції та обробка помилок у SQL Server

Порівняння рівнів ізоляції

Брудні читання Неповторювані читання Фантомні читання
READ UNCOMMITTED так так так
READ COMMITTED ні так так
REPEATABLE READ ні ні так
SERIALIZABLE ні ні ні
Транзакції та обробка помилок у SQL Server

Блокування записів у SERIALIZABLE

  • Запит з WHERE на основі діапазону індексу -> Блокує лише ці записи
  • Запит не на основі діапазону індексу -> Блокує всю таблицю
Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит на основі діапазону індексу

Транзакція 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 |

Запис заблоковано

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит на основі діапазону індексу

Транзакція 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 |

Запис заблоковано

Транзакція 2

...

...

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

Має чекати!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит на основі діапазону індексу

Транзакція 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 |

Транзакція 2

...

...

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

Має чекати!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит на основі діапазону індексу

Транзакція 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

Транзакція 2

...

...

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

Нарешті виконано!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит на основі діапазону індексу

Транзакція 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 |

Транзакція 2

...

...

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

Миттєво вставлено!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит не на основі діапазону індексу

Транзакція 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 |

Блокує всю таблицю

Транзакція 2

...

...

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

Має чекати!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит не на основі діапазону індексу

Транзакція 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 |

Транзакція 2

...

...

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

Має чекати!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — запит не на основі діапазону індексу

Транзакція 1

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

    SELECT * FROM customers;
COMMIT TRAN

Транзакція 2

...

...

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

Нарешті виконано!

Транзакції та обробка помилок у SQL Server

SERIALIZABLE — підсумок

Переваги:

  • Добра узгодженість даних: блокує брудні, неповторювані та фантомні читання

Недоліки:

  • Вас можуть заблокувати транзакції SERIALIZABLE

Коли використовувати?

  • Коли узгодженість даних критично важлива
Транзакції та обробка помилок у SQL Server

Давайте потренуємось!

Транзакції та обробка помилок у SQL Server

Preparing Video For Download...