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

Трябва да създам номер на фактура във формат:

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