MYSQL INNODB Ручное увеличение с блокировкой

ID|RID|SID|Name
 1| 1 | 1 |Alpha
 2| 1 | 2 |Beta
 3| 2 | 1 |Charlie

ID уникален с автоинкрементом, проблема не в этом. RID группирует наборы данных вместе, мне нужен способ сделать SID уникальным для каждой группы RID. Эта структура верна, я ожидаю, что кто-то скажет «разделить ее на несколько таблиц», здесь это не вариант (это таксономическая классификация).

Как показано, при RID 1 SID увеличивается с 1 до 2, но когда RID изменяется на 2, SID равен 1.

У меня есть код для получения следующего значения: SELECT IFNULL(MAX(SID),0)+1 AS NextVal FROM t WHERE RID=1, вопрос в том, как использовать это значение при вставке новой записи?

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


person user2949952    schedule 24.03.2014    source источник


Ответы (1)


Сначала вы должны ограничить свои данные, чтобы они были именно такими, какими вы хотите их видеть, поэтому поместите уникальный комбинированный индекс на (RID, SID).

Для вашей проблемы вы должны запустить транзакцию (BEGIN), а затем поставить монопольную блокировку на нужные вам строки, которая блокирует весь доступ к этим строкам для других соединений (не всей таблицы, что плохо для производительности!):

SELECT .... FOR UPDATE

Это блокирует исключительно все выбранные строки. Кроме того, вы не должны не использовать READ UNCOMMITTED в качестве уровня изоляции. вы можете просмотреть в руководстве, как проверить текущую уровень изоляции и как его изменить. REPEATABLE READ — это уровень изоляции по умолчанию, который здесь подойдет.

Затем вставьте новый запрос и зафиксируйте (COMMIT) транзакцию.

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

person Ulrich Thomas Gabor    schedule 24.03.2014