Вопрос

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

+--------------+-----------------------+
| user_id      | name                  |
+--------------+-----------------------+
| 1            | Bob                   |
| 1            | Marry                 |
| 2            | Bob                   |
| 1            | John                  |
| 3            | Bob                   |
| 2            | Marry                 |
+--------------+-----------------------+

При каждой вставке я увеличиваю user_id на 1, так что, например, следующий user_id для Bob будет равен 4

Я использую этот запрос, чтобы сделать это:

INSERT INTO users (user_id, name)
SELECT 1 + coalesce((SELECT max(user_id) FROM users WHERE name='Bob'), 0), 'Bob';

Теперь мне нужно убедиться, что два разных пользователя не добавляют 'Bob' одновременно.Мне не нужны никакие два Bobs с user_id 4.Каждый из идентификаторов пользователя Bob должен отличаться.

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

Это было полезно?

Решение

Предполагая, что InnoDB здесь, вы можете использовать ВЫБЕРИТЕ ...БЛОКИРОВКА В РЕЖИМЕ ОБЩЕГО ДОСТУПА чтобы заблокировать строки при их выборе.

Другие советы

Чтобы решить первую часть вашего вопроса, создайте уникальный индекс для идентификатора пользователя и имени.

alter table `users` add unique index ak_user_id_name(user_id,name);

Это предотвратит дублирование записей user_id,name.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top