2010-11-15 4 views
0

Эй, ребята, вот что я не могу понять. У нас есть таблица в базе данных, где PHP вставляет записи. Я создал триггер для вычисления значения, которое нужно вставить. Вычисленное значение должно быть уникальным. Однако время от времени случается, что у меня точно такое же число для нескольких строк в таблице. Номер представляет собой комбинацию года, месяца и дня и номер заказа на этот день. Я думал, что одиночная операция вставки является атомарной, а таблица заблокирована во время транзакции. Мне нужно, чтобы вычисленное значение было уникальным ... Сервер версии 5.0.88. Сервер - это Linux CentOS 5 с двухъядерным процессором.Операции и триггеры MySQL

Вот триггер:

CREATE TRIGGER bi_order_data BEFORE INSERT ON order_data 
FOR EACH ROW BEGIN 
    SET NEW.auth_code = get_auth_code(); 
END; 

Соответствующие рутинные выглядит так:

CREATE FUNCTION `get_auth_code`() RETURNS bigint(20) 
BEGIN 
    DECLARE my_auth_code, acode BIGINT; 
    SELECT MAX(d.auth_code) INTO my_auth_code 
     FROM orders_data d 
     JOIN orders o ON (o.order_id = d.order_id) 
     WHERE DATE(NOW()) = DATE(o.date); 

    IF my_auth_code IS NULL THEN 
     SET acode = ((DATE_FORMAT(NOW(), "%y%m%d")) + 100000) * 10000 + 1; 
    ELSE 
     SET acode = my_auth_code + 1; 
    END IF; 
    RETURN acode; 
END 
+0

Почему бы вам не включить время до ms. Или введите номер последовательности/auto-increment и добавьте его. – Jules

+0

Я второй номер автоинкремента, если вы не используете какой-либо внутренний метод для счетчиков, у вас будет риск состояния гонки – ZaQ

+0

Ну ... Каждая строка имеет уникальный автоинкремент no. Однако подсчитанный номер используется для других целей. Заказ вводится в таблицу, после чего тонкая машина автоматически выбирает ее и отправляет ее для обработки устаревшей системой. После этого порядок в таблице изменяется по статусу, когда он проходит через машину с конечным состоянием. Унаследованная система поддерживает 10-значное число в описанном формате. Поэтому добавление автоинкремента остановит систему после 9999 заказов всего ... – user390133

ответ

2

Я думал, что одна операция из вставки атомарный и таблица заблокирована пока транзакция находится в прогресс

Либо таблица заблокирована (используется MyISAM), либо записи могут быть заблокированы (используется InnoDB), а не оба.

Поскольку вы упомянули «транзакцию», я предполагаю, что InnoDB используется. Одним из преимуществ InnoDB является отсутствие блокировок таблиц, поэтому ничто не предотвратит одновременное выполнение нескольких тел триггеров и даст тот же результат.

Смежные вопросы