Блокировка максимального значения в MySQL
Я использую следующий запрос на MySQL с использованием PHP
$sql = SELECT MAX(SrNo) FROM cart;
$result = mysql_query($sql);
Структура таблицы CART
CART (SrNo int(10));
Теперь я использую результат, чтобы выполнить некоторую обработку и вставить максимальное значение в эту таблицу, увеличив его на единицу. Моя проблема в том, что если user1 получил максимальное значение SrNo
и находится между обработкой. В течение этого времени пользователь user2 также запрашивает, чтобы сервер получил то же максимальное значение SrNo, что и пользователь user1, и начинает обработку.
Теперь, когда оба будут выполнены с обработкой + вставкой в таблицу, у меня будет два дубликата в таблице CART. Как я могу предотвратить это?
Другими словами, я не хочу, чтобы кто-то еще получил максимальное значение SrNo
до тех пор, пока один пользователь не закончит свою обработку.
3 ответа
Вы не будете в порядке с функцией AUTO_INCREMENT для PRIMARY KEY?
create table cart ( SrNo int(10) AUTO_INCREMENT PRIMARY KEY ) ENGINE = InnoDB;
затем просто вставьте новые строки, и он автоматически увеличит новые значения. Это, вероятно, очень легко сделает трюк, который вы (возможно?) Пытаетесь сделать.
Но если вам нужно заблокировать maxmium, вы можете сделать это:
start transaction;
select max(SrNo) from cart for update;
/* do some other stuff, insert the max value + 1 etc... */
commit;
Помните: вы должны использовать транзакцию для любой операции, которая не является одним запросом!
НЕТ тривиальной вещи с веб-приложением, которое создает новое соединение при каждом запросе. Вам нужно добавить lockedBy
а также lockedTime
столбцы к этой таблице, и положить в них ID
пользователя, который запросил блокировку, а также отметку времени, когда была запрошена блокировка. Вам нужна временная метка, чтобы вы могли игнорировать блокировки, которые длиннее определенного времени.
Если вы установите SrNo в качестве первичного ключа в таблице, то второе время, когда вы попытаетесь добавить строку, приведет к сбою, а в случае неудачи вы можете запросить новый номер.
ALTER TABLE cart ADD PRIMARY KEY (SrNo);