#mysql #sql #transactions #scalability
Вопрос:
У меня есть mysql Innodb
таблица m
со следующей схемой id, name, type , newid
, и комбинация name, type ,newid
должна быть уникальной. У меня есть 2 набора types
, и, следовательно, для них обоих новый идентификатор должен быть последовательным. (Я ничего не могу сделать с первым id
полем) Я написал транзакцию, которая будет выглядеть следующим образом
begin
select max(newid) where name = name and type = type =>fetchedID
insert into m values (name, type, fetchedID 1)
commit
Теперь это работает нормально для обычной записи. Но для масштабируемой системы с несколькими записями, которые должны быть вставлены одновременно, я столкнулся с проблемой, когда одни и те же fetchedID
данные были извлечены в 2 разных записи ( max(newid)
получались одни и те же значения для нескольких транзакций, а именно. одновременное чтение).
Так что немного ТАК и гугление помогли мне найти SELECT ... FOR UPDATE
решение.
Но это удерживает блокировку бд в течение достаточного времени, чтобы другие транзакции, готовые к выполнению, не выполнялись. Как мне сделать эту систему работающей и масштабируемой.
Комментарии:
1. Простой ответ: вы не можете заставить это работать в параллельной среде. Забудьте, что newid является порядковым номером, вместо этого используйте uuid или метку времени (если вы хотите указать порядок).
2. @Тень, но в этом вся задача. Чтобы получить последовательный идентификатор для упомянутого набора. Кроме того, поправьте меня, если я ошибаюсь, под одновременным вы подразумеваете одновременный доступ нескольких клиентов к таблице и попытку изменить ее одновременно, верно ?
3. Зачем вам нужен отдельный идентификатор?
4. Если что-то должно быть уникальным, добавьте уникальный индекс. Затем 2-я вставка одновременно вызовет ошибку, и вы можете просто повторить ее (например, с помощью 2 или путем повторного выбора max()).
5. Вам не нужно поддерживать свой собственный последовательный идентификатор. Используйте
IDENTITY
тип илиSEQUENCE
.