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

Редактировал(а) Alexandr Fokin 2024/05/28 20:47

Последние авторы
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 |(% style="width:155px" %)REPEATABLE READ|(% style="width:614px" %)(((
19 |MSSQL|{{code language="sql"}}SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
20 BEGIN TRANSACTION
21
22 if (SELECT balance FROM accounts /*FOR UPDATE*/ where acctnum = @account2 ) < @payment
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 TRANSACTION ISOLATION LEVEL REPEATABLE READ;
36
37 if (SELECT balance FROM accounts where acctnum = @account2 ) < @payment
38 RAISE EXCEPTION ''
39 END IF
40
41 UPDATE accounts
42 SET balance = balance + @payment
43 WHERE acctnum = @account1
44
45 UPDATE accounts
46 SET balance = balance - @payment
47 WHERE acctnum = @account2
48
49 COMMIT;{{/code}}|
50 | | |
51 )))|(% style="width:652px" %)(((
52 * Предварительная проверка условия перед изменением строк.
53 Гарантия, что значение не будет изменено другими транзакциями после проверки (или их изменение будет обнаружено и приведет к ошибке).
54 * В запросе могут использоваться как относительные, так и константные значения, при условии что значение было сформировано после проверки допустимости операции.
55
56 ----
57
58 Данное поведение также может быть реализовано на уровне READ COMMITTED, но для этого нужно использовать механизм явных блокировок (обычно это что-то вроде UPDLOCK).
59 (Причем для данного примера явная блокировка была бы обязательна только для проверяемого аккаунта, с которого выполняется списание).
60 )))