Используете ли вы базу данных SQL для создания своего новостного приложения? Вас замедляют две вещи: объектно-реляционное отображение (например, ActiveRecord) и транзакции.

Сегодня поговорим о транзакциях.

Что такое транзакция?

Убедите множество пользователей ВСТАВИТЬ, ОБНОВИТЬ и УДАЛИТЬ строки в вашей базе данных. Заставьте их продолжать это делать. Затем подумайте, что находится в вашей базе данных прямо сейчас. А потом сейчас. А потом сейчас.

Каждое мгновение ваша база данных действительна. Отключите компьютер и перезагрузите его. Это все еще в силе.

Ваша база данных перескакивает с транзакции на транзакцию, как будто в каждый момент времени пишет только один человек. Это называется соответствие ACID.

Разве это не хорошо?

Вы, конечно, хотите, чтобы ваша база данных снова заработала после отключения компьютера.

Кроме того, транзакции не всегда ведут себя так, как вам хотелось бы.

Скажем, два пользователя посещают страницу, и вы запускаете этот SQL для каждого:

UPDATE pages SET n_comments = n_comments + 1 WHERE id = 2;

Вы гарантированно выполняете только одну запись за раз. А как насчет чтения?

Как ни странно, «n_comments + 1» — это чтение. Если оба пользователя запустят этот запрос одновременно, они оба прочитают одно и то же значение для «n_comments + 1». Тогда на вашей странице будет отображаться неправильное количество комментариев.

Короче говоря: транзакции подвержены ошибкам. Они не решают проблемы, которые вы от них ожидаете. В общем, быстрых решений нет.

(Это не относится к моему эссе, но есть быстрое решение этой конкретной проблемы: SET n_comments = SELECT COUNT(*) FROM comments WHERE page_id = 2;)

Хорошо, но чем транзакции могут быть плохими?

Во-первых, транзакции позволяют вам чувствовать себя комфортно, когда вы не должны этого делать. Плохо.

Кроме того, транзакции могут быть медленными.

Допустим, вы импортируете данные. У вас есть одна большая транзакция с множеством операций INSERT, UPDATE и DELETE. Пока вы выполняете транзакцию, система базы данных поддерживает все эти строки отдельно от остальных данных на случай, если в конце вы не совершите COMMIT. Существует много бухгалтерии, которую вы не можете контролировать. И прежде чем вы это осознаете, вы можете столкнуться с причудливым исходом: вашей крупной транзакции может потребоваться слишком много времени для COMMIT… и слишком долго для ROLLBACK. Вы застряли с непригодной для использования базой данных.

Теперь рассмотрим маленькие транзакции. Если у вас много пользователей и вы делаете что-то, когда они нажимают, это относится и к вам. Чтобы обеспечить сохранность ваших данных, ваша система баз данных может часто выполнять fsync(). Это очень медленно — намного медленнее, чем реальный процесс написания вещей.

Значит, мне не следует использовать транзакции?

Если вы используете SQL, каждый запрос находится в транзакции. Вы не можете избежать транзакций.

Если ваша база данных работает медленно, у вас есть два варианта:

  1. Настройте систему базы данных специально для вашего новостного приложения. Например, отключите автоматическую fsync. (На практике это может быть очень сложно, особенно если вы запускаете два приложения, которым нужны разные вещи, или если вы делитесь своим проектом с другими разработчиками.)
  2. Не используйте SQL. (На практике это часто бывает легко.)

Что вам не нравится в SQL?

Это решение некоторых проблем. Но это может быть не лучшим решением для вашей проблемы.

Подумайте о своем следующем новостном приложении. Вероятно, вы ожидаете, что ваши пользователи сделают несколько вещей (скажем, пять). Вы ожидаете X кликов и хотите, чтобы каждый ответ пришел через Y секунд. Вы заполните базу данных Z мегабайтами данных…

Продолжайте обдумывать свое новостное приложение. Подумайте, как вы будете его использовать. Подумайте, как ваши пользователи будут его использовать. Подумайте, где вы будете получать данные и как поддерживать их в актуальном состоянии. Думай, думай и думай часами…

… и вы никогда не подумаете: Мне нужны и транзакции, и соответствие ACID, и «индексы b-tree, и ассоциативные таблицы, и зрелый язык манипулирования данными.

Это основные функции SQL-серверов. Для большинства новостных приложений все они бесполезны.

Ладно, сейчас погуглю. Вернемся к моей основной мысли.

У транзакций есть преимущества, но они могут не применяться к вашему новостному приложению. У транзакций есть недостатки, и они, вероятно, имеют значение для вашего новостного приложения.

И если вы используете SQL, вы должны использовать транзакции.