Получить уникальный номер из файла, содержащего список номеров одновременно
У меня есть список уникальных номеров в файле. Всякий раз, когда пользователь моего сайта делает запрос, мне нужно получить значение из этого списка, чтобы ни один другой пользователь не получил такое же значение. Может быть много одновременных запросов, и, следовательно, основная проблема заключается в том, чтобы гарантировать, что никакие два пользователя не получат одинаковое значение. Меня не беспокоит производительность в том смысле, что пользователь не ожидает ответа после выполнения запроса, поэтому все может происходить в фоновом режиме. Из того, что я прочитал, это может быть реализовано с помощью файловых блокировок или я могу хранить данные в БД и использовать блокировки БД. Я просто хочу получить представление о том, как лучше всего это сделать. Я использую postresql в качестве базы данных, и мне было интересно, можно ли это сделать, используя последовательности, в которых я сохраняю текущий номер строки в последовательности, чтобы моя программа знала, какую строку читать из БД. Но опять же, я не уверен, как запретить нескольким процессам читать одну и ту же строку, прежде чем какой-либо из них сможет обновить ее.
1 ответ
Базы данных на самом деле не делают много вещей, но то, что они делают, они делают очень хорошо. В частности, они обрабатывают параллельный доступ к данным. Вы можете использовать это в ваших интересах:
- Создать таблицу:
create table special_number (id serial, num varchar(100) not null);
- Обеспечить уникальность:
create unique index special_number_num on special_number(num);
- Загрузите свои числа в таблицу, используя
COPY
, позволяя идентификатору считать от 1 автоматически - Создайте последовательность:
create sequence num_seq;
- Используйте тот факт, что Postgres's
nextval
Функция гарантированно параллельна и безопасна для безопасного выбора номера из списка:select num from special_number where id = (select nextval('num_seq'));
, Это вернетсяnull
если у вас закончились номера.
Этот подход на 100% безопасен и прост - внутренняя сила Postgres как базы данных делает всю тяжелую работу.
Вот SQL извлеченный сверху:
create table special_number (id serial, num varchar(100) not null);
create unique index special_number_num on special_number(num);
copy special_number(num) from '/tmp/data.txt'; -- 1 special number per file line
create sequence num_seq;
select num from special_number where id = (select nextval('num_seq'));
Этот SQL был протестирован на postgres и работает как положено.