Использование уникального индекса MySQL с хорошей атомарностью без ошибок - PullRequest
1 голос
/ 27 марта 2012

У меня есть эта таблица:

User
    id INT PK
    login VARCHAR UNIQUE

Я хочу знать, как лучше всего обрабатывать вставку уникальных индексов (например, создание нового пользователя)

1) Я могу просто ВСТАВИТЬ, и когда возникает «повторяющаяся запись», я ловлю исключение и обрабатываю его в приложении

=> Я не уверен, что это лучшее решение для этого

2) Я могу выбрать SELECT ... WHERE login = ... затем INSERT, если запись не найдена, или отобразить ошибку, если select что-то нашел

=> Это не атомарно, вставка может происходить между SELECT и INSERT

3) Я могу начать транзакцию, ВЫБЕРИТЕ ДЛЯ ОБНОВЛЕНИЯ, ВСТАВИТЬ, затем УСТАВИТЬ, когда записи не найдены, или ОТКРЫТЬ, и отобразить ошибку, если пользователь уже существует

=> Это просто не будет работать, так как MySQL не блокирует никакие существующие строки ... Так что это, безусловно, приведет к тупику

Так, как лучше всего справиться с этим очень простым примером?

Ответы [ 2 ]

0 голосов
/ 27 марта 2012

Как я вижу, у вас есть два варианта:

1) Используйте Блокировка таблиц и SELECT, затем Insert. Блокировка стола гарантирует, что вы не попадете в состояние гонки.

2) Если вас беспокоит блокировка таблицы, вы можете сделать первый из перечисленных вариантов: INSERT или еще лучше INSERT IGNORE. Если вы используете INSERT IGNORE, исключение для дубликата ключа будет возвращено как предупреждение.

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

0 голосов
/ 27 марта 2012

Вы можете сделать

INSERT IGNORE ...

ВСТУПЛЕНИЕ MySQL вручную

Или

REPLACE ...

ЗАМЕНА MySQL ЗАМЕНА

Также вы можете принять некоторые ответы на ваши вопросы.Это побудит больше людей помогать вам.

...