Я создаю систему для генерации уникальных ключей. Это работает на данный момент. Но я не проверял это со многими пользователями. Пользователи могут нажать кнопку, а затем получить свой уникальный номер, такой же простой.
Но, как запретить нескольким пользователям получать одинаковые уникальные клавиши, если они нажимают кнопку точно в одно и то же время (даже в масштабе мс)? Кнопка на стороне клиента, поэтому я должен сделать что-то на заднем плане.
Это уникальный ключ выглядит так:
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
Похоже, что вы не хотите выходить и рассказывать нам, какая платформа для этого или каковы ограничения для этой платформы.
Первое, что бросается в глаза, это то, что ваш формат ограничен годом, до 999999 уникальных ключей. Очень странно, но, по-видимому, вы понимаете этот предел, и вам нужно будет добавить код, чтобы справиться с достижением максимального числа.
подходы
Основанный на REDIS
Это было бы очень просто с сервером REDIS, использующим INCR. Поскольку INCR является атомарным, у вас, по сути, есть решение, просто создав ключ с именем для вашего года + 2, если он не существует, и используя для этого INCR.
Вы должны будете использовать некоторые PHP Redis клиент, и есть множество из них с сильными и слабыми сторонами, в которые я не буду вдаваться.
Redis также отлично подходит для кеширования, так что, если это вообще возможно, это первое, на что я бы обратил внимание.
MySQL Based
Есть несколько разных решений, использующих mysql. Они вовлечены, поэтому я просто обрисую их, потому что я не хочу тратить время на написание романа.
Замечания: YВам нужно будет перевести их в соответствующий код PHP (mysqli или PDO), где, как отмечалось, параметры передаются, транзакции запускаются и т. д.
MySQL — создайте свой собственный генератор последовательностей
Создайте таблицу с именем «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 будут обслуживать кластер, так что это более надежные варианты с этой точки зрения.
Важно то, что что бы вы ни делали, вы проверяете это с помощью нагрузочного тестера, такого как осада или же заграждение генерировать несколько запросов на вашем веб-уровне.
Других решений пока нет …