<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Максим Кузнецов: заметки с тегом acid</title>
<link>https://maxkuznetsov.ru/tags/acid/</link>
<description>Простыми словами о веб-разработке</description>
<author>Максим Кузнецов</author>
<language>ru</language>
<generator>E2 (v3559; Aegea)</generator>

<itunes:owner>
<itunes:name>Максим Кузнецов</itunes:name>
<itunes:email></itunes:email>
</itunes:owner>
<itunes:subtitle>Простыми словами о веб-разработке</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>Базы данных, транзакции и ACID</title>
<guid isPermaLink="false">18</guid>
<link>https://maxkuznetsov.ru/all/db-acid/</link>
<pubDate>Thu, 09 Apr 2020 00:34:00 +0300</pubDate>
<author>Максим Кузнецов</author>
<comments>https://maxkuznetsov.ru/all/db-acid/</comments>
<description>
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://maxkuznetsov.ru/pictures/acid2.jpg" width="600" height="266" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;i&gt;Транзакция&lt;/i&gt; — набор команд, которые должны быть выполнены одной пачкой, так как представляют собой одну бизнес операцию.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Пример: транзакция по переводу денег состоит из команд «списать деньги с отправителя», «начислисть деньги адресату».&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;ACID&lt;/i&gt; — это требования к транзакциям и системам, работающим с ними (например, базам данных). ACID требует, чтобы каждая транзакция&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;не зависала в середине пути в случае ошибки, а откатывала все сделанные изменения (атомарность),&lt;/li&gt;
&lt;li&gt;после своего завершения не оставляла данные неконсистентными (консистентность),&lt;/li&gt;
&lt;li&gt;не влияла на другие транзакции (на самом деле влияла, но как можно меньше — 4 уровня изолированности),&lt;/li&gt;
&lt;li&gt;а вся система гарантировала, что выполненные транзакции будут запомнены системой даже при возникновении аварий и форс-мажоров (стойкость, durability).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;Подробнее о каждом требовании и с примерами&lt;/summary&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;b&gt;Atomicity/Атомарность&lt;/b&gt; требует, чтобы либо все команды транзакции были выполнены, либо ни одной. То есть транзакция должна действовать как единая атомарная команда.
&lt;br/&gt;&lt;br/&gt;
На практике атомарность реализуется через версионирование и откаты (rollback) команд транзакции до первоначального состояния базы. Строго говоря, индексы могут обратно не откатиться, но чаще всего СУБД это разруливают сами.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Сonsistency/Консистентность&lt;/b&gt; требует, чтобы после завершения транзакции данные оставались консистентными и валидными, т. е. чтобы они не имели логических или технических противоречий.
&lt;br/&gt;&lt;br/&gt;
Пример: суммарный баланс счетов должен оставаться неизменным (логическая К.), запись одной таблицы не должна ссылаться на удалённый айдишник другой записи (техническая К.).
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;b&gt;Isolation/Изолированность&lt;/b&gt; — при параллельном выполнении транзакции не должны влиять друг на друга. 
&lt;/p&gt;
&lt;p&gt;
Пример: если два человека одновременно делают денежный перевод третьему, то одна транзакция в теории может перезаписать значения другой, и деньги потеряются. Изолированность исключает такую ситуацию.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Durability/Стойкость&lt;/b&gt; — если транзакция завершена успешно, то она не может быть отменена даже при авариях, внезапном отключении света в датацентре и проблем в сети. В этом случае база данных должна сама восстановить последние транзакции.
&lt;/ol&gt;
&lt;h2&gt;Уровни изолированности в базах данных&lt;/h2&gt;
&lt;p&gt;На практике изолированность сложна в реализации и сильно влияет на производительность системы. Поэтому базы данных могут работать с четырьмя уровнями изолированности (от меньшей надёжности к большей).&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;
        &lt;p&gt;&lt;b&gt;Read uncommitted&lt;/b&gt; — позволяет избежать «потерянных обновлений», когда две транзакции обновляют одно и то же значение/строку.&lt;/p&gt;
        &lt;p&gt;На этом уровне UPDATE-транзакции резервируют данные для себя и блокируют для других UPDATE-транзакций. Тем не менее, SELECT-запросы не блокируются и даже могут считать промежуточное состояние данных, возникающие между выполнением команд одной транзакции.&lt;/p&gt;
        &lt;p&gt;Пример: транзакция на перевод денег состоит из команды на списание денег с одного счёта и команды пополнения другого счёта. На момент изменения баланса счёта первой транзакцией вторая подобная транзакция встанет в очередь, пока данные не освободятся. Но SELECT-запрос может считать состояние, когда деньги списаны с одного счёта, но на второй ещё не зачислены.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
         &lt;p&gt;&lt;b&gt;Read committed&lt;/b&gt; — то же, что выше + решает проблему чтения «грязных» состояний незавершённых транзакций. Большинство баз данных по умолчанию работает на этом уровне изолированности.&lt;/p&gt;
         &lt;p&gt;Однако если транзакция содержит две SELECT-команды и во время между ними другая UPDATE-транзакция успешно завершится, то результат этих SELECT-запросов может отличваться: один вернёт состояние до UPDATE-транзакции, второй — после. Важно, что это не «грязное» состояние, а чистое, после успешной транзакции.&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
         &lt;p&gt;&lt;b&gt;Repeatable read (повторяемость чтения)&lt;/b&gt; — оба пункта выше + гарантирует, что SELECT-запросы в рамках одной транзакции всегда будут возвращать один и тот же результат, даже если другие транзакции обновляют или удаляют эти же данные. &lt;/p&gt;
         &lt;p&gt;Транзакция блокирует все строки, затрагиваемые её командами, включая SELECT, а другие транзакции с SELECT-, UPDATE- и DELETE-запросами к этим данным ждут её завершения. Естественно, это сильно снижает скорость обработки транзакций базой данных.
         &lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
         &lt;p&gt;&lt;b&gt;Serializable&lt;/b&gt; — три пункта выше + исключает «фантомные чтения». &lt;/p&gt;
         &lt;p&gt;«Фантомное чтение» похоже на проблему с двумя последовательными SELECT-запросами одной транзакции, но возникает, когда между SELECT-запросами была выполнена именно вставка (INSERT). Пример: аггрегационные запросы SELECT SUM(), SELECT COUNT().
         &lt;/p&gt;
         &lt;p&gt;Это максимальный уровень изолированности. При нём транзакции выполняются так, будто других параллельных транзакций не существует.&lt;/p&gt;
   &lt;/li&gt;
  &lt;/ol&gt;
&lt;p&gt;&lt;/details&gt;&lt;br /&gt;
&lt;br/&gt;&lt;/p&gt;
</description>
</item>


</channel>
</rss>