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