Подтвердить что ты не робот

Увеличивает ли поле в атоме MySQL?

Я создаю веб-сайт, где я бы хотел увеличить счетчик в стандартной таблице MyISAM.

Упрощенный пример:

UPDATE votes SET num = num + 1;

Это вызовет проблемы, если несколько подключений выполняют один и тот же запрос или MySQL позаботится об этом и заблокирует таблицу или что-то, чтобы убедиться, что конфликтов нет?

4b9b3361

Ответ 1

В таблицах MyISAM используется блокировка уровня таблицы. Это означает, что вся таблица будет заблокирована во время выполнения вашего запроса на обновление. Таким образом, ответ для вашего упрощенного варианта использования: да, это поточно-безопасный. Но это может быть не так, если вы используете другой механизм хранения или ваше обновление включает несколько таблиц.

Вот цитата из руководства MySQL для большей ясности:

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

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

Ура!

Ответ 2

Запись является атомарной, но приращение также требует чтения. Поэтому возникает вопрос: уверены ли вы, что чтение безопасно, другими словами, вы уверены, что другой поток, выполняющий приращение, не будет иметь такое же значение, которое нужно увеличить? У меня есть сомнения. 100% правильный способ сделать это будет.

-- begin transaction here

select counter from myCounters where counter_id = 1 FOR UPDATE;

-- now the row is locked and nobody can read or modify its values

update myCounters set counter = ? where id = 1;

-- set ? to counter + 1 programmatically

commit; -- and unlock...

Ответ 3

Да, таблица (или строки в базах данных InnoDB) автоматически блокируется при выполнении запроса на обновление.

Ответ 4

Эта форма UPDATE является атомарной. Другие формы UPDATE могут быть сделаны атомарными, используя транзакции с SELECT ... FOR UPDATE.

Ответ 5

Имел ту же проблему, хотя запрос был более сложным:

UPDATE CLB_SYNC_T SET PENDING_MESSAGES = PENDING_MESSAGES + ? WHERE USER_ID = ?

Использование MyISAM в качестве механизма по умолчанию не помогло, поэтому я возвращаюсь к SELECT FOR UPDATE.

С ВЫБОР ДЛЯ ОБНОВЛЕНИЯ производительность улучшилась ~ 10 раз, так как MySQL не заблокировал всю таблицу, чтобы сделать обновление строки.

Ответ 6

Другой подход при использовании InnoDB использует уникальный индекс для нескольких столбцов следующим образом:

Таблица "Сессии" { unique_key (browser_session_id, profile_id)//гарантирует, что вставка 1 записи в сеанс произойдет один раз }

выберите count (browser_session_id) из сеансов

Гарантирует результат уникальных сеансов, поскольку несколько сеансов на пользователя не разрешены.

Выводы

  • Преимущество

    Каждая вставка требует предварительного выбора.

  • Неудобство

    Он не подходит для всех случаев.

    Может замедлить производительность записи и требует дополнительного управления