Duplicate Key при вставке нескольких записей с увеличенными идентификаторами перед вставкой в ​​Node.js - PullRequest
0 голосов
/ 12 января 2020

Недавно я столкнулся с проблемой. Я постараюсь описать это как можно лучше и проще.

В обработчике BEFORE INSERT я получаю только тело, а для генерации идентификатора я получаю следующее доступное число, которое делится на 10 от уже существующие записи в БД, и я назначаю ее новой вставляемой записи.

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

Я использую HanaDB, node.js, с пользовательским обработчиком cds перед вставкой, но, насколько я искал, эта проблема не связана, в частности, ни с одной из технологий, которыми я владею используя.

У кого-нибудь есть идеи, как я могу избежать этого, но при этом сохраняю лог c для увеличенных идентификаторов? (Насколько я знаю, у меня есть доступ только к обработчику BEFORE INSERT)

Допустим, у меня есть таблица UserItems с одной записью. (Составлено PK от USER и ITEM)

USER    ITEM    DESCRIPTION

1001    10      nice description

Теперь я хочу добавить еще 2 пользовательских элемента параллельно, чтобы вывод был таким:

USER    ITEM    DESCRIPTION

1001    10      nice description
1001    20      nice description 2
1001    30      nice description 3

Но так как это сделано через пользовательский обработчик (промежуточное ПО), который получает следующее число, которое делится на 10 доступных (20 и 30 после этого), и поскольку запросы выполняются параллельно, он выдает ошибку Duplicate Key.

По сути, промежуточное ПО просматривает существующие данные, получает идентификатор 20, вставляет одну запись, но когда приходит другой запрос для 3-го пользовательского элемента, когда код будет искать в базе данных, чтобы получить другие id он увидит только одну запись

1001    10      nice description

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

1 Ответ

0 голосов
/ 13 января 2020

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

Попытка гарантировать упорядоченность и разрыв Последовательности в общих структурах данных (таблицах базы данных) требуют блокировки в некоторой форме. Это делает его bottle -обогом для обработки вставок в вашем приложении.

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

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

...