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

Версия 1.28 от Alexandr Fokin на 2024/05/28 16:15

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