Здравствуйте.
Редакция старт.
Написал свой модуль и лежим в local/modules/my.name/Order/OrderTable.php
Это описанная модель таблицы с заказами.
Те у нас есть таблица, в которой есть поля id, user_id, delivery_id ....
вообщем много полей всяких и одно из эти х полей называется order_num и имеет строковый формат
Как вы уже навреное догадались это номер заказа и он должен быть уникальным (именно номер а не id в базе)
class OrderTable extends Entity\DataManager
{
public static function getTableName()
{
return 'dch_order';
}
public static function getMap()
{
return array(
new Entity\IntegerField('ID', array(
'primary' => true,
'autocomplete' => true
)),
new Entity\StringField('ORDER_NUM', array(
'required' => false
)),
.......
}
Описание модели примерно такое (выше)
У меня стояла задача присваивать номер заказу уникальный
самый простой случай - это брать последний номер и прибавлять 1 - получается новый номер заказа
решил я это через события и в том же файле local/modules/my.name/Order/OrderTable.php добавил
public static function onBeforeAdd(Entity\Event $event)
{
$result = new Entity\EventResult;
$data = $event->getParameter("fields");
if (!$data['ORDER_NUM']) {
$resOrders = OrderTable::getList([
'select' => ['ID', 'DATE_CREATE', 'ORDER_NUM'],
'order' => ['ORDER_NUM' => "DESC"],
'filter' => ['!ORDER_NUM' => false],
'limit' => 1
]);
if ($arOrder = $resOrders->fetch()) {
$newOrderNum = (int)$arOrder['ORDER_NUM'] + 1;
$result->modifyFields(['ORDER_NUM' => $newOrderNum]);
}
}
return $result;
}
Те у меня где-то далеко в коде есть функция создания заказа, она вообще в другом классе, внутри которой я вызываю
$res = OrderTable:add([...]);
$orderId = res->getId();
Когда запись в БД вот-вот готова и есть все поля (но без поля номер заказа),
далее срабатывает событие onBeforeAdd, которое берет и ищет в таблице с заказ заказ с последним номером
получает его (номер) и присваивает ему +1 - это получается номер для нового заказа
далее уже идет сохранение в базу.
Код работает и давно, но вот недавно стали появляться заказы с одинаковыми номерами (1-2 раза в месяц), посмотрел, а у них дата создания совпадает до секунды, подозреваю, что событие onBeforeAdd когда делает выборку, то работает с одним набором данных, а когда присваивает, то уже с другим, вроде бы это коллизия называется или нарушение консистентности данных. (те заказы создаются в 1 секунду и для нас получается onBeforeAdd 2 раза работает для каждого заказа и получает одинаковый последний номер, тк работает одновременно)
Помогите найти решение, которое бы не создавало мне одинаковых номеров заказов (не сохраняло в базу строки с одинаковым полем)
Заранее благодарен за помощь!