<?xml version="1.0" encoding="utf-8"?>
<!-- If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/ -->
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:lj="http://www.livejournal.com">
  <id>urn:lj:livejournal.com:atom1:eugenecoder</id>
  <title>Дневник Евгения Кодина</title>
  <subtitle>eugenecoder</subtitle>
  <author>
    <name>eugenecoder</name>
  </author>
  <link rel="alternate" type="text/html" href="http://eugenecoder.livejournal.com/"/>
  <link rel="self" type="text/xml" href="http://eugenecoder.livejournal.com/data/atom"/>
  <updated>2008-03-02T01:37:50Z</updated>
  <lj:journal userid="14738843" username="eugenecoder" type="personal"/>
  <link rel="service.feed" type="application/x.atom+xml" href="http://eugenecoder.livejournal.com/data/atom" title="Дневник Евгения Кодина"/>
  <link rel="hub" href="http://pubsubhubbub.appspot.com/"/>
  <entry>
    <id>urn:lj:livejournal.com:atom1:eugenecoder:1302</id>
    <link rel="alternate" type="text/html" href="http://eugenecoder.livejournal.com/1302.html"/>
    <link rel="self" type="text/xml" href="http://eugenecoder.livejournal.com/data/atom/?itemid=1302"/>
    <title>Немного о транзакциях в MySQL</title>
    <published>2008-03-02T01:33:17Z</published>
    <updated>2008-03-02T01:37:50Z</updated>
    <content type="html">Здравствуйте, дорогие читатели.&lt;br /&gt;&lt;br /&gt;Приводя в порядок один из проектов я наткнулся на неочевидную ошибку, которую совершает невообразимое количество программистов. Общий смысл кода был такой:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
// Запрещаем коммит
$hasApprovedCommit = false;

// начинаем транзакцию
query("START TRANSACTION");

// Вставляем некоторую запись в таблицу
query("
    INSERT INTO
        table 
    SET 
        key='value'
");

// Создаем таблицу
query("
    CREATE TABLE test (
        id INT auto_increment,
        key VARCHAR(255),
        
        PRIMARY KEY(id)
    )
");

// Откат или коммит?
if ($hasApprovedCommit) {
    query("COMMIT");
}
else {
    query("ROLLBACK");
}
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;По мнению автора кода ни новой записи в таблице table, ни таблицы test в базе появиться не должно было. Однако, несмотря на его ожидания, и запись добавилась и таблица создалась.&lt;br /&gt;&lt;br /&gt;Разберемся в проблеме подробнее.&lt;br /&gt;&lt;br /&gt;Конструкции в MySQL делятся на два вида - откатываемые и неоткатываемые. К конструкциям, которые невозможно откатить, относятся конструкции языка определения данных (data definition language, DDL), что очевидно — некоторые ALTER-запросы могут выполняется по нескольку часов и откат таких запросов был бы чрезмерно ресурсоемким.&lt;br /&gt;&lt;br /&gt;Камнем преткновения этого кода является то, что конструкция CREATE TABLE не просто неоткатываемая — если таковая конструкция попадается в транзакции, она автоматически вызывает COMMIT всех предыдущих конструкций.&lt;br /&gt;&lt;br /&gt;Полный перечень таких конструкций перечислен здесь:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/refman/4.1/en/implicit-commit.html"&gt;http://dev.mysql.com/doc/refman/4.1/en/implicit-commit.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;К сожалению, такие ошибки очень сложно локализовывать и потому при написании транзакций следует проявлять особенную бдительность.</content>
  </entry>
</feed>
