AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 10.02.2023, 18:08   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Контроль уникальности с условием dax2012
Есть таблица с полями: ItemId, Status

Status - это Enum, который может принимать значения "Активный", "Неактивный"

Есть периодичка, которая обновляет данные в этой таблице, но только среди записей со статусом "Активный". Если записи нет, то создает новую. Тоже со статусом "Активный"

Проблема в том, что если будет запущено сразу 2 периодички разными пользователями, то есть риск получить "дубли"

Как правило, проблема дублей решается созданием уникального индекса. Но здесь проблема в том, что контролировать уникальность надо не по всем записям, а только среди записей со статусом "Активный"

Проверка в триггере смысла не имеет, поскольку именно эта проверка и делается внутри периодички. Новая запись создается именно в случае, когда такой записи не нашли. Значит, скорее всего, и триггер это не поймает

Какие есть варианты решения проблемы в dax2012?

PS: Вариант запрета запуска периодички по каким-либо условиям - не рассматривается
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 10.02.2023, 18:17   #2  
Pandasama is offline
Pandasama
Участник
 
449 / 133 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
А блокировку вешать на таблицу, пока запущенная одним пользователем функция создает эту запись?
Старый 10.02.2023, 19:56   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Pandasama Посмотреть сообщение
А блокировку вешать на таблицу, пока запущенная одним пользователем функция создает эту запись?
Если именно в момент создания одной записи, то поиск записи выполняется до попытки ее создания. Т.е. саму проблему это не решит. Блокировку сняли и вторая операция тут же создаст дубль. Решение о том, что ее надо создать было принято до перехода в режим ожидания снятия блокировки

Если же блокировать в самом начале операции, то это означает запрет выполнения операции вторым пользователем, пока первый не завершит обработку. Специально указал, что такое решение не подходит
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 10.02.2023, 20:51   #4  
Pandasama is offline
Pandasama
Участник
 
449 / 133 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Ну, я не знаю вашей задачи.
Но мне кажется, вы что-то усложняет.

Блокируйте перед проверкой "надо создавать или нет", если надо - создавайте и потом сразу разблокируйте.
Или у вас такой большой разрыв между проверкой и созданием записи? Почему?
Старый 10.02.2023, 21:07   #5  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Т.е. не одну общую транзакцию на всю операцию, а по транзакции на каждую вставку/обновление одной записи в одной таблице?

Нет. Такое решение неприемлемо
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 10.02.2023, 21:19   #6  
ТРЕНЕР is offline
ТРЕНЕР
Участник
Аватар для ТРЕНЕР
 
598 / 49 (3) +++
Регистрация: 11.06.2003
Адрес: Москва
Допустим ли для вашей задачи такой сценарий, чтобы запущенные другими пользователями операции смотрели, не запущена ли уже та же операция другим пользователем, и если запущена - то ждали бы пока она завершится, и только тогда начинали свою обработку?
Если это приемлимо - то дальше вы сами знаете как делать.
Старый 10.02.2023, 21:25   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от ТРЕНЕР Посмотреть сообщение
Допустим ли (..) ждали бы (...), и только тогда начинали свою обработку?
Гм...

Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
PS: Вариант запрета запуска периодички по каким-либо условиям - не рассматривается
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 10.02.2023, 22:27   #8  
ena_ax is offline
ena_ax
Участник
 
254 / 46 (2) +++
Регистрация: 06.12.2006
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Т.е. не одну общую транзакцию на всю операцию, а по транзакции на каждую вставку/обновление одной записи в одной таблице?

Нет. Такое решение неприемлемо
Можете подробнее раскрыть что значит неприемлемо?
По форме вопроса решение выглядит вполне подходящим.
Спрашиваю исключительно для своего понимания и интереса.
Если не затруднит.
Старый 10.02.2023, 22:38   #9  
ТРЕНЕР is offline
ТРЕНЕР
Участник
Аватар для ТРЕНЕР
 
598 / 49 (3) +++
Регистрация: 11.06.2003
Адрес: Москва
Ну это же не запрет запуска. Это ожидание. Которое возможно продлится не более нескольких секунд и для пользователя будет не выглядеть запретом.

Могу предложить другой вариант: не апдейтить каждую запись сразу, а сначала собирать записи требующие апдейта в список, и потом одним update recordset все сразу записать.
Старый 10.02.2023, 23:23   #10  
macklakov is offline
macklakov
NavAx
Аватар для macklakov
 
2,129 / 916 (35) +++++++
Регистрация: 03.04.2002
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Нет. Такое решение неприемлемо
Мне но очень понятна причина таких ограничений. Но можно попробовать поиграться с locks.
Или хакерский подход. Сделать 2 отдельных поля Активный и Неактивный. Тогда получится индекс только по активным. А корректность флажков контролировать через код вставки.
__________________
Isn't it nice when things just work?
Старый 11.02.2023, 00:49   #11  
axm2017 is offline
axm2017
Участник
 
1,757 / 292 (13) ++++++
Регистрация: 15.05.2017
✓Но здесь проблема в том, что контролировать уникальность надо не по всем записям, а только среди записей со статусом "Активный"

Почему не вынести статусы номенклатур в отдельную таблицу типа история статусов?
Старый 11.02.2023, 14:23   #12  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,486 / 408 (16) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Проблема в том, что если будет запущено сразу 2 периодички разными пользователями, то есть риск получить "дубли"
Так может проще назначить одного уполномоченного и запретить всем остальным?
__________________
С уважением,
Вячеслав
Старый 11.02.2023, 21:24   #13  
ТРЕНЕР is offline
ТРЕНЕР
Участник
Аватар для ТРЕНЕР
 
598 / 49 (3) +++
Регистрация: 11.06.2003
Адрес: Москва
Есть еще простой вариант - сделать пакетное задание, которое будет постоянно искать и удалять дубли. Его разработка займет в десятки раз меньше времени, чем вы УЖЕ ПОТРАТИЛИ на поиск решения.
Старый 11.02.2023, 22:08   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Как правило, проблема дублей решается созданием уникального индекса. Но здесь проблема в том, что контролировать уникальность надо не по всем записям, а только среди записей со статусом "Активный"
Организовать контроль уникальности на уровне индекса в такой ситуации можно так:
1) Делаете в таблице дополнительное уникальное поле (например копирующее RecId), но заполняете его только для "Неактивных" записей.
2) Включаете это поле в индекс, который должен быть уникальным только для "Активных" записей
3) Делаете этот индекс уникальным для всей таблицы
За это сообщение автора поблагодарили: Logger (3), trud (2).
Старый 12.02.2023, 10:32   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,875 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
2 Kuskov
Много раз так делали и все отлично работает.
Более того, для тех записей где доп поле равно нулю можно еще заставить и кеш работать

Кстати в уникальное поле удобнее писать не RecId а eventId. Для его выделения есть стандартный статический метод.
Старый 12.02.2023, 16:35   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Предложенные варианты
  1. Изменение бизнес-процесса (транзакция, таблицы архива и т.п.)
  2. Запрет одновременного выполнения несколькими процессами (программно или организационно)
  3. Новое поле для симуляции уникального индекса по условию
  4. Удаление дублей "постфактум". После выполнения операции

Вкратце поясню.

Я не разрабатывал этот бизнес-процесс. Ко мне пришли уже с проблемой, которую надо решить. Любые варианты советов на тему, что Вам надо сам бизнес-процесс менять или организовать его выполнение по другому - заранее обречены. Никто на это не пойдет.

Т.е. по сути, выбор стоит между созданием нового поля и удалением "постфактум". На настоящий момент заказчик выбрал вариант удаления "постфактум". Правда, не в отдельной периодичке, а как завершающая операция в этом же процессе, но в отдельной транзакции

Если других вариантов решения нет, то на этом можно и закончить. Всех благодарю за участие.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 12.02.2023, 21:04   #17  
ТРЕНЕР is offline
ТРЕНЕР
Участник
Аватар для ТРЕНЕР
 
598 / 49 (3) +++
Регистрация: 11.06.2003
Адрес: Москва
Годится ли то или иное решение - можно сказать только понимая весь бизнес-процесс целиком.

И какой у вас заказчик интересный: не только работает, но и принимает решения в воскресенье..
Старый 16.02.2023, 22:05   #18  
DarkSpirit22 is offline
DarkSpirit22
Участник
Аватар для DarkSpirit22
 
13 / 76 (3) ++++
Регистрация: 07.11.2013
Адрес: СПб
В голову еще приходит SQL filtered unique index:
X++:
create table MyTable (a int
                    , b nvarchar(10)
                    , Id int identity(1,1) primary key)

CREATE UNIQUE INDEX idx_MyTable_filtered
ON MyTable (b)
WHERE a = 1

/*Вставилось:*/
insert into MyTable (a,b) values
(0, 'AAAA'),
(0, 'AAAA'),
(0, 'AAAA'),
(1, 'BBBB')

/*Ошибка:*/
insert into MyTable (a,b) values
(1, 'BBBB')
За это сообщение автора поблагодарили: gl00mie (5).
Старый 16.02.2023, 22:54   #19  
axm2017 is offline
axm2017
Участник
 
1,757 / 292 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Предложенные варианты
[LIST=1][*]Изменение бизнес-процесса ... таблицы архива
В моем понимании это не изменение бизнес процесса.
Просто статусы записываются в отдельную табличку. Некая нормализация скорее. За счёт этого избегаем блокировки при параллельной работе.
Старый 17.02.2023, 12:43   #20  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,875 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от DarkSpirit22 Посмотреть сообщение
В голову еще приходит SQL filtered unique index:
А как вы его из аксапты сделаете, да еще и гарантируете, что он не слетит при следующей синхронизации ?
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Бюджетирование AX2012 RU2- контроль нескольких бюджетов mnt_dx DAX: Функционал 4 11.12.2015 12:56
kurthatlevik: DAX2012 R3 – Playing with Retail CRT Blog bot DAX Blogs 0 21.05.2015 15:11
DAX2012 - перепоставки по закупкам Starling DAX: Функционал 2 18.03.2014 13:56
Контроль даты поставки + Авторезервирование kart DAX: Функционал 0 21.07.2011 11:44
Контроль серийных номеров и сторно закупки, по которой нет остатка Starling DAX: Функционал 6 01.02.2011 14:55

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:47.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.