Исходный код вики Примеры.

Версия 1.32 от Alexandr Fokin на 2025/09/19 15:03

Последние авторы
1 (% style="width:1426px" %)
2 |(% style="width:155px" %)**Необходимый уровень изоляции**|(% style="width:614px" %)**Запрос**|(% style="width:652px" %)**Комментарий**
3 |(% style="width:155px" %) |(% style="width:614px" %) |(% style="width:652px" %)Замечание: в приведенных ниже примерах не рассматриваются сценарии с использованием [[Оптимистичная блокировка>>doc:Архитектура и модели.Блокировки.Оптимистичная блокировка.WebHome]].
4 |(% style="width:155px" %)READ COMMITTED|(% style="width:614px" %){{code language="sql"}}BEGIN;
5
6 UPDATE accounts
7 SET balance = balance + @payment
8 WHERE acctnum = @account1
9
10 UPDATE accounts
11 SET balance = balance - @payment
12 WHERE acctnum = @account2
13
14 COMMIT;{{/code}}|(% style="width:652px" %)(((
15 * Относительное изменения значения (а не константное).
16 * Без проверок.
17
18 (В данном случае строка заблокируется в момент обновления, чтение (select) с проверкой без явного указания updlock, то строка может быть изменена после проверки условия).
19 )))
20 |(% style="width:155px" %)REPEATABLE READ|(% style="width:614px" %)(((
21 |MSSQL|{{code language="sql"}}SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
22 BEGIN TRANSACTION
23
24 if (SELECT balance FROM accounts /*FOR UPDATE*/ where acctnum = @account2 ) < @payment
25 //error
26 END IF
27
28 UPDATE accounts
29 SET balance = balance + @payment
30 WHERE acctnum = @account1
31
32 UPDATE accounts
33 SET balance = balance - @payment
34 WHERE acctnum = @account2
35
36 COMMIT;{{/code}}|
37 |Postgres|{{code language="sql"}}BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
38
39 if (SELECT balance FROM accounts where acctnum = @account2 ) < @payment
40 RAISE EXCEPTION ''
41 END IF
42
43 UPDATE accounts
44 SET balance = balance + @payment
45 WHERE acctnum = @account1
46
47 UPDATE accounts
48 SET balance = balance - @payment
49 WHERE acctnum = @account2
50
51 COMMIT;{{/code}}|
52 | | |
53 )))|(% style="width:652px" %)(((
54 * Предварительная проверка условия перед изменением строк.
55 Гарантия, что значение не будет изменено другими транзакциями после проверки (или их изменение будет обнаружено и приведет к ошибке).
56 * В запросе могут использоваться как относительные, так и константные значения, при условии что значение было сформировано после проверки допустимости операции.
57
58 (В данном случае чтение (select) накладывает share блокировку, что гарантирует, что строка не будет изменена).
59
60 ----
61
62 Данное поведение также может быть реализовано на уровне READ COMMITTED, но для этого нужно использовать механизм явных блокировок (обычно это что-то вроде UPDLOCK).
63 (Причем для данного примера явная блокировка была бы обязательна только для проверяемого аккаунта, с которого выполняется списание).
64 )))