Как не дать двум пользователям получить один и тот же уникальный ключ?

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

Но, как запретить нескольким пользователям получать одинаковые уникальные клавиши, если они нажимают кнопку точно в одно и то же время (даже в масштабе мс)? Кнопка на стороне клиента, поэтому я должен сделать что-то на заднем плане.

Это уникальный ключ выглядит так:
19/XXXXXX-ABC/XYZ

XXXXXX это номер автоинкремента от 000001 в 999999, У меня есть этот код, но я не знаю, достаточно ли он надежен для решения моей проблемы.

    $autoinc = $this->MPenomoran->get_surat($f_nomor)->jumlah_no+1; //count data in table and added 1

$no_1   = date('y')+2;
$no_2   = str_pad($autoinc, 6, '0', STR_PAD_LEFT);
$no_3   = "-ABC/XYZ";

$nomor      = $no_1."/".$no_2.$no_3;

$returned_nomor     = $nomor;

$success =  array ('nomor' => $returned_nomor); //sent unique keys to user's view

2

Решение

Похоже, что вы не хотите выходить и рассказывать нам, какая платформа для этого или каковы ограничения для этой платформы.

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

подходы

Основанный на REDIS

Это было бы очень просто с сервером REDIS, использующим INCR. Поскольку INCR является атомарным, у вас, по сути, есть решение, просто создав ключ с именем для вашего года + 2, если он не существует, и используя для этого INCR.

Вы должны будете использовать некоторые PHP Redis клиент, и есть множество из них с сильными и слабыми сторонами, в которые я не буду вдаваться.

Redis также отлично подходит для кеширования, так что, если это вообще возможно, это первое, на что я бы обратил внимание.

MySQL Based

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

Замечания: YВам нужно будет перевести их в соответствующий код PHP (mysqli или PDO), где, как отмечалось, параметры передаются, транзакции запускаются и т. д.

MySQL — создайте свой собственный генератор последовательностей

  1. Создайте таблицу с именем «Sequence» с этой базовой структурой:

    name varchar(2) PK
    nextval unsigned int default 1

    двигатель = ЬшоВВ

Основной запрос будет выглядеть примерно так:

BEGIN_TRANS;
SELECT nextval FROM Sequence WHERE name = '$no_1' FOR UPDATE;
UPDATE Sequence SET nextval = nextval + 1;
END_TRANS;

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

MySQL — автоинкремент на многозначном ПК

Это идет с некоторыми оговорками.

Это вообще несовместимо с репликацией.
Основная таблица должна быть myisam

name varchar(2) PK
lastval unsigned int AUTO_INCREMENT PK
engine=MyISAM

Ваш основной запрос будет:

INSERT INTO Sequence (name) VALUES ('$no_1')

Это зависит от поддержки MySQL многостолбцового ключа, где 2-й столбец — AUTO_INCREMENT. Это поведение таково, что оно действует как последовательность для каждого уникального имени.

Затем вы бы использовали встроенный подход соответствующего API для получения mysql LAST_INSERT_ID (). Например с PDO

Другие альтернативы

Вы также можете использовать семафоры, файлы с блокировкой и всевозможные другие идеи для создания генератора последовательностей, который будет хорошо работать в монолитной (один сервер на все) среде. MySQL и Redis будут обслуживать кластер, так что это более надежные варианты с этой точки зрения.

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector