Блокировки и тайм-ауты прерывают транзакции ACID - PullRequest
1 голос
/ 13 июля 2011

У меня есть транзакционное приложение, которое работает следующим образом:

try {
     $db->begin();
     increaseNumber();
     $db->commit();
} catch(Exception $e) {
     $db->rollback();
}

А затем внутри incrementNumber () у меня будет примерно такой запрос, который является единственной функцией, которая работает с этой таблицей:

// I use FOR UPDATE so that nobody else can read this table until its been updated
$result = $db->select("SELECT item1
FROM units
WHERE id = '{$id}'
FOR UPDATE");

$result = $db->update("UPDATE units SET item1 = item1 + 1
WHERE id = '{$id}'");

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

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

Это должно произойти или что-то еще не так??

Спасибо, Доминик

Ответы [ 2 ]

2 голосов
/ 13 июля 2011

Хорошо, если транзакция сталкивается с блокировкой (из другой транзакции), которая не освобождается, она завершится ошибкой по истечении времени ожидания.Я считаю, что по умолчанию 30 секунд.Вы должны сделать заметку, если кто-либо использует сторонние приложения в базе данных.Я точно знаю, что, например, SQL Manager 2007 не снимает блокировки на InnoDB, если вы не отключаетесь от базы данных (иногда для этого требуется только принятие транзакции на ... ну,все), что приводит к сбою многих запросов после тайм-аута.Конечно, если ваши транзакции совместимы с ACID, они должны выполняться «все или ничего».Он сломается, только если вы разбиваете данные между транзакциями.

Вы можете попытаться увеличить время ожидания, но 30-секундная блокировка может повлечь за собой некоторые более глубокие проблемы.Конечно, это зависит от того, какой механизм хранения вы используете (по тегу MySQL и транзакциям, которые я предполагал InnoDB).

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

1 голос
/ 13 июля 2011

A в ACID означает Atomic, поэтому никакие взаимоблокировки не могут прервать транзакцию ACID - скорее, это не сделает так, как в случае «все или ничего».

Скорее всего, если вы противоречивые данные,Ваше приложение выполняет несколько «транзакций» в рамках одной логической транзакции, например: пользователь создает учетную запись (транзакция-начало ..- коммит), пользователь устанавливает пароль (транзакция-начало ...- тупик ..- откат)Ваше приложение проигнорировало ошибку и продолжает работу, и теперь ваша база данных остается с созданным пользователем и без пароля.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...