Как запретить двум процессам Node вставлять одну и ту же запись базы данных при одновременной работе? - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть лямбда, которая получает тысячи событий одновременно. Параллелизм остается по умолчанию, что означает, что AWS раскручивает несколько экземпляров для обработки входящих событий Лямбда берет данные и вставляет некоторые данные в базу данных, если эти данные еще не существуют. Лямбда написана на Node.js и использует Knex для подключения к базе данных Postgres.

Лямбда, по сути, содержит эту логику:

Does a record with ID X exist?     
a. Yes: do nothing
b. No: create a new record with ID X.

Проблема заключается в том, что, когда 50 лямбдодей раскручиваются одновременно, они входят в состояние гонки, где, скажем, 3 или 4 из них будут проверять существующую запись одновременно (или в течение микросекунд друг от друга). ) и не найти его, поэтому вставляю несколько повторяющихся записей.

Я знаю, что одним из способов решения этой проблемы было бы создание уникального ограничения на таблицу для предотвращения нескольких записей с идентификатором X. Тогда моя логика будет выглядеть следующим образом:

Does a record with ID X exist? 
a. Yes: do nothing 
b. No: create a new record with ID X.
   b.1. Did that succeed?
      a. Yes: continue on.
      b. No, it threw a unique constraint error: go back to line 1.

Это кажется немного надуманным, но должно работать. Есть ли лучший вариант?

EDIT:

Вот фактический код:

let location = await Location.query().where({ external_id }).first();
if(!location){
    location = await Location.query().insert({
        name,
        external_id
    });
}

1 Ответ

2 голосов
/ 19 апреля 2019

Код такой:

Does a record with ID X exist?      
a. Yes: do nothing 
b. No: create a new record with ID X.

без блокировки базы данных как-то является условием гонки. Между запросом записи X и ее созданием может быть создан другой запрос. Не делай так, никогда. Это колоритно.

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

...