Генератор атомарных порядковых номеров MySQL

#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, получите снова).

Вопрос:

  1. Выполняет ли эта функция атомарную
  2. Любой другой способ сделать это правильно?

Таблица : 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. Кажется работоспособным, будет отмечен как ответ после того, как я провел еще несколько тестов. Огромное спасибо, шмосел