Уникальный номер документа за месяц

Мне нужно создать номер счета в формате:

CONSTANT_STRING/%d/mm/yyyy

mm - месяц (две цифры) yyyy - год

Теперь % d - это номер счета за определенный месяц. Другими словами, это число сбрасывается каждый месяц.

Теперь я проверяю в базе данных, какое наибольшее число в текущем месяце. Затем после увеличения я сохраняю строку.

Мне нужно, чтобы все число было уникальным. Однако иногда случается, что он дублируется (два пользователя сохраняют одновременно).

Какие-либо предложения?


person Cleankod    schedule 17.01.2011    source источник
comment
у вас есть unique_identifier в этой таблице? ты не можешь это использовать? или, возможно, отметка времени, чтобы выяснить, какая запись появилась первой?   -  person Duniyadnd    schedule 17.01.2011
comment
какой движок базы данных вы используете для своей таблицы?   -  person Mark Baker    schedule 17.01.2011


Ответы (4)


Поместите уникальный индекс в поле и перехватите ошибку базы данных при попытке сохранить второй экземпляр. Также отложите получение значения до последнего возможного момента.

person Ignacio Vazquez-Abrams    schedule 17.01.2011

Одно из решений - SELECT ... FOR UPDATE, которое блокирует строку до тех пор, пока вы ее не обновите, но может вызвать взаимоблокировки в серьезном многозадачном приложении.

Лучший способ - получить номер и увеличить его в транзакции, а затем начать работу. Таким образом, строка не блокируется надолго.

Посмотрите на BEGIN WORK и COMMIT.

person Ciprian L.    schedule 17.01.2011

Используйте первичный ключ (предпочтительно INT) таблицы счетов-фактур или присвойте уникальный номер каждому счету-фактуре, например через uniqid.

PS. Если вы используете uniqid, вы можете увеличить уникальность, установив для параметра more_entropy значение true.

person miku    schedule 17.01.2011

установить идентификатор все в одном запросе.

$query = 'INSERT INTO table (invoice_number) VALUES (CONCAT(\''.CONSTANT.'\', \'/\', (SELECT COUNT(*) + 1 AS current_id FROM table WHERE MONTH(entry_date) = \''.date('n').'\' AND YEAR(entry_date) = \''.date('Y').'\'), \'/\', \''.date('m/Y').'\'))';
person dqhendricks    schedule 17.01.2011