HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Не все операции с базой данных можно выразить одним запросом. Например, так нельзя сделать с транзакцией, когда нужно перевести деньги с одного счета на другой. В этом уроке разберем, как выполнять запросы внутри транзакции. Также узнаем, какие существуют требования к транзакционной системе, чтобы она оставалась надежной.</p>
1 <p>Не все операции с базой данных можно выразить одним запросом. Например, так нельзя сделать с транзакцией, когда нужно перевести деньги с одного счета на другой. В этом уроке разберем, как выполнять запросы внутри транзакции. Также узнаем, какие существуют требования к транзакционной системе, чтобы она оставалась надежной.</p>
2 <h2>Запросы внутри транзакции</h2>
2 <h2>Запросы внутри транзакции</h2>
3 <p>Допустим, у нас есть таблица счетов<em>accounts</em>, в которой две записи:</p>
3 <p>Допустим, у нас есть таблица счетов<em>accounts</em>, в которой две записи:</p>
4 <p><a>View on DB Fiddle</a></p>
4 <p><a>View on DB Fiddle</a></p>
5 <p>Процесс перевода можно представить так:</p>
5 <p>Процесс перевода можно представить так:</p>
6 <ol><li><p>Получаем количество денег пользователя:</p>
6 <ol><li><p>Получаем количество денег пользователя:</p>
7 </li>
7 </li>
8 <li><p>Списываем необходимую сумму со счета этого пользователя:</p>
8 <li><p>Списываем необходимую сумму со счета этого пользователя:</p>
9 </li>
9 </li>
10 <li><p>Зачисляем деньги другому пользователю:</p>
10 <li><p>Зачисляем деньги другому пользователю:</p>
11 </li>
11 </li>
12 </ol><p>В результате таблица примет следующий вид:</p>
12 </ol><p>В результате таблица примет следующий вид:</p>
13 <p><a>View on DB Fiddle</a></p>
13 <p><a>View on DB Fiddle</a></p>
14 <p>Одна из проблем в этом процессе -- отсутствует гарантия завершения. Представим, что система успела выполнить списание, и в этот момент произошла ошибка, например, выключили питание или компьютер перезагрузился. В результате получится странная ситуация: деньги списались, но никуда не зачислились:</p>
14 <p>Одна из проблем в этом процессе -- отсутствует гарантия завершения. Представим, что система успела выполнить списание, и в этот момент произошла ошибка, например, выключили питание или компьютер перезагрузился. В результате получится странная ситуация: деньги списались, но никуда не зачислились:</p>
15 <p>Такое может произойти не только с деньгами, но и в большинстве других ситуаций. Приложения по возможности должны находиться в согласованном состоянии. В распределенных системах это невозможно, добиться этого можно с помощью механизма<strong>транзакций</strong>. Мы не будем подробно разбирать эту тему, но вы можете узнать о ней больше, изучив<a>CAP-теорему</a>и<a>Eventual Consistency</a>.</p>
15 <p>Такое может произойти не только с деньгами, но и в большинстве других ситуаций. Приложения по возможности должны находиться в согласованном состоянии. В распределенных системах это невозможно, добиться этого можно с помощью механизма<strong>транзакций</strong>. Мы не будем подробно разбирать эту тему, но вы можете узнать о ней больше, изучив<a>CAP-теорему</a>и<a>Eventual Consistency</a>.</p>
16 <p>Транзакции используют не только в базах данных, но и в обычной жизни. Например, операция снятия денег в банкомате -- это бизнес-транзакция. Пользователи банкомата ожидают, что эта операция либо снимет деньги, либо нет, и банкомат это обеспечивает.</p>
16 <p>Транзакции используют не только в базах данных, но и в обычной жизни. Например, операция снятия денег в банкомате -- это бизнес-транзакция. Пользователи банкомата ожидают, что эта операция либо снимет деньги, либо нет, и банкомат это обеспечивает.</p>
17 <p>Операция снятия денег -- это процесс, который приводит не только к множеству запросов в базу данных, но и к затрагиванию многих систем. У них есть свои процессы и базы данных внутри.</p>
17 <p>Операция снятия денег -- это процесс, который приводит не только к множеству запросов в базу данных, но и к затрагиванию многих систем. У них есть свои процессы и базы данных внутри.</p>
18 <p>Мы ожидаем от любой подобной транзакции<strong>атомарность</strong>-- когда операция либо завершается успешно, либо не проходит. Транзакции в базе данных в этом смысле проще, чем бизнес-транзакции. За обеспечением необходимых гарантий следит сама СУБД, а не программист:</p>
18 <p>Мы ожидаем от любой подобной транзакции<strong>атомарность</strong>-- когда операция либо завершается успешно, либо не проходит. Транзакции в базе данных в этом смысле проще, чем бизнес-транзакции. За обеспечением необходимых гарантий следит сама СУБД, а не программист:</p>
19 <p><a>View on DB Fiddle</a></p>
19 <p><a>View on DB Fiddle</a></p>
20 <p>Транзакции в PostgreSQL -- это блок запросов, который обрамляется запросами:</p>
20 <p>Транзакции в PostgreSQL -- это блок запросов, который обрамляется запросами:</p>
21 <ul><li>BEGIN -- открытие транзакции</li>
21 <ul><li>BEGIN -- открытие транзакции</li>
22 <li>COMMIT -- закрытие транзакции</li>
22 <li>COMMIT -- закрытие транзакции</li>
23 </ul><p>Любая ошибка внутри транзакции откатывает все изменения, которые были сделаны после запроса BEGIN:</p>
23 </ul><p>Любая ошибка внутри транзакции откатывает все изменения, которые были сделаны после запроса BEGIN:</p>
24 <p>Если нужно, транзакцию можно откатить самостоятельно. Для этого необходимо выполнить запрос ROLLBACK до COMMIT. Это нужно, когда выполняются запросы из кода приложения.</p>
24 <p>Если нужно, транзакцию можно откатить самостоятельно. Для этого необходимо выполнить запрос ROLLBACK до COMMIT. Это нужно, когда выполняются запросы из кода приложения.</p>
25 <p><a>View on DB Fiddle</a></p>
25 <p><a>View on DB Fiddle</a></p>
26 <p>Также, чтобы транзакция была надежной и предсказуемой, нужно соблюдать определенные требования.</p>
26 <p>Также, чтобы транзакция была надежной и предсказуемой, нужно соблюдать определенные требования.</p>
27 <h2>Требования к транзакционной системе</h2>
27 <h2>Требования к транзакционной системе</h2>
28 <p>В информатике есть набор требований к транзакционной системе, которые гарантируют ее надежность --<strong>ACID</strong>. К ним относятся:</p>
28 <p>В информатике есть набор требований к транзакционной системе, которые гарантируют ее надежность --<strong>ACID</strong>. К ним относятся:</p>
29 <ul><li>Atomicity (Атомарность)</li>
29 <ul><li>Atomicity (Атомарность)</li>
30 <li>Consistency (Согласованность)</li>
30 <li>Consistency (Согласованность)</li>
31 <li>Isolation (Изолированность)</li>
31 <li>Isolation (Изолированность)</li>
32 <li>Durability (Устойчивость)</li>
32 <li>Durability (Устойчивость)</li>
33 </ul><p>Разберем каждое требование подробнее</p>
33 </ul><p>Разберем каждое требование подробнее</p>
34 <h3>Atomicity (Атомарность)</h3>
34 <h3>Atomicity (Атомарность)</h3>
35 <p>Любая транзакция не может быть частично завершена -- она либо выполнена, либо нет.</p>
35 <p>Любая транзакция не может быть частично завершена -- она либо выполнена, либо нет.</p>
36 <h3>Consistency (Согласованность)</h3>
36 <h3>Consistency (Согласованность)</h3>
37 <p>Завершившаяся транзакция должна сохранять согласованность базы данных. Каждая успешная транзакция фиксирует только допустимые результаты, при том, что в процессе работы транзакции данные могут оказываться несогласованными.</p>
37 <p>Завершившаяся транзакция должна сохранять согласованность базы данных. Каждая успешная транзакция фиксирует только допустимые результаты, при том, что в процессе работы транзакции данные могут оказываться несогласованными.</p>
38 <p>В примере выше снятие денег с одного счета приводит к тому, что данные рассинхронизированы. Но когда транзакция завершается, этого нет.</p>
38 <p>В примере выше снятие денег с одного счета приводит к тому, что данные рассинхронизированы. Но когда транзакция завершается, этого нет.</p>
39 <p>Гарантию согласованности данных нельзя полностью обеспечить только средствами базы данных, например, различными ограничениями. Поддержка этого требования включает в себя работу со стороны программистов, которые пишут необходимый для этого код.</p>
39 <p>Гарантию согласованности данных нельзя полностью обеспечить только средствами базы данных, например, различными ограничениями. Поддержка этого требования включает в себя работу со стороны программистов, которые пишут необходимый для этого код.</p>
40 <h3>Isolation (Изолированность)</h3>
40 <h3>Isolation (Изолированность)</h3>
41 <p>Когда транзакция выполняется, параллельные транзакции не должны оказывать влияния на ее результат. Ни одна транзакция не может увидеть изменения, которые сделаны другими незавершенными транзакциями. Изолированность -- дорогое требование, поэтому в реальных БД существуют режимы, которые изолируют транзакцию не полностью -- уровни изолированности Repeatable Read и ниже.</p>
41 <p>Когда транзакция выполняется, параллельные транзакции не должны оказывать влияния на ее результат. Ни одна транзакция не может увидеть изменения, которые сделаны другими незавершенными транзакциями. Изолированность -- дорогое требование, поэтому в реальных БД существуют режимы, которые изолируют транзакцию не полностью -- уровни изолированности Repeatable Read и ниже.</p>
42 <h3>Durability (Устойчивость)</h3>
42 <h3>Durability (Устойчивость)</h3>
43 <p>Изменения, которые сделаны успешно завершенной транзакцией, должны остаться сохраненными после возвращения системы в работу. И это не должно зависеть от проблем на нижних уровнях, к примеру, обесточивание системы или сбои в оборудовании. Если пользователь получил подтверждение от системы, что транзакция выполнена, он будет уверен, что ничего не отменится из-за какого-либо сбоя.</p>
43 <p>Изменения, которые сделаны успешно завершенной транзакцией, должны остаться сохраненными после возвращения системы в работу. И это не должно зависеть от проблем на нижних уровнях, к примеру, обесточивание системы или сбои в оборудовании. Если пользователь получил подтверждение от системы, что транзакция выполнена, он будет уверен, что ничего не отменится из-за какого-либо сбоя.</p>
44 <h2>Выводы</h2>
44 <h2>Выводы</h2>
45 <p>Мы разобрали, как выполнять запросы внутри транзакции. Такие операции нельзя выполнить за один запрос, поэтому нужно проходить несколько шагов. Также мы узнали, что к транзакционной системе существуют требования ACID: атомарность, согласованность, изолированность и устойчивость. Этот набор свойств транзакции гарантирует, что данные в БД будут целостные независимо от любых сбоев.</p>
45 <p>Мы разобрали, как выполнять запросы внутри транзакции. Такие операции нельзя выполнить за один запрос, поэтому нужно проходить несколько шагов. Также мы узнали, что к транзакционной системе существуют требования ACID: атомарность, согласованность, изолированность и устойчивость. Этот набор свойств транзакции гарантирует, что данные в БД будут целостные независимо от любых сбоев.</p>