#mysql #c
#mysql #c
Вопрос:
Моя программа требует генерировать УНИКАЛЬНЫЙ идентификатор транзакции через MySQL из-за множества машинных сред.
Я использую следующую функцию MySQL, я просматриваю Google, она не атомарна, как я думаю.
DELIMITER $$
CREATE DEFINER=`` FUNCTION `getNextTXID`(dummy INT) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE txid bigint(20);
SET txid = (SELECT next_txid FROM txid_seq LIMIT 1 FOR UPDATE);
IF txid > 15000000 THEN
SET txid = 0;
END IF;
UPDATE txid_seq SET next_txid = txid 500 LIMIT 1;
RETURN txid;
END
Я ранее использовал last_insert_id
, но было введено новое требование для сброса после 15M числа. Я не могу воспроизвести условие гонки, любые 2 из 100 процессов фактически получают один и тот же номер транзакции (в пакете из 500, если приложение израсходовало все 500, получите снова).
Вопрос:
- Выполняет ли эта функция атомарную
- Любой другой способ сделать это правильно?
Таблица : MyISAM
Механизм хранения : MyISAM
Автоматическая фиксация : TRUE
Редактировать:
я использую MySQL C API. Заранее спасибо за любую заявку.
Комментарии:
1. Почему ваша функция помечена как
DETERMINISTIC
?
Ответ №1:
Это не атомарно, потому что вы читаете и записываете отдельно. Но это должно выполнять ту же операцию атомарно, при этом возвращая значение из LAST_INSERT_ID()
:
UPDATE txid_seq SET next_txid = LAST_INSERT_ID((next_txid * (next_txid <= 15000000)) 500) LIMIT 1;
Комментарии:
1. Кажется работоспособным, будет отмечен как ответ после того, как я провел еще несколько тестов. Огромное спасибо, шмосел