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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.03.2014, 17:25   #1  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
PurchLine update conflict ??
Мне нужно присвоить новые значения полю PurchLine.PurchReceivedNow , код приблизительно такой:
X++:
ttsBegin;
     while select forupdate purchLine
    order by Confirmeddlv
    where   purchLine.PurchId        == purchId &&
                 purchLine.ItemId                == itemId  &&         
                 purchLine.PurchStatus     == PurchStatus::Backorder &&
               (!purchLine.IsDeleted)
    exists join InventDim
      where lalala           
   {
           // purchLine.reread();
            if (receivedQty >= purchLine.RemainPurchPhysical)
            {
                purchLine.PurchReceivedNow = purchLine.RemainPurchPhysical;
                receivedQty -= purchLine.RemainPurchPhysical;
            }
            else
            {
                purchLine.PurchReceivedNow = receivedQty;
                receivedQty = 0;
            }
           
            purchLine.setInventReceivedNow();
            purchLine.Tax1099Amount = 0;
            purchLine.Tax1099StateAmount = 0;
    

            if (purchLine.validateWrite())
            {
                purchLine.update();
            }
            else
            {
               throw error('my error');
            }
    }
Вопрос: Если убрать reread, то система валится с updateConflict. Не могу понять, что делаю не так. По идее код корректно должен работать и без него. Нашла ссылку на похожую проблему вот тут . Что приводит к updateconflict?

Ax2012 R2

Последний раз редактировалось IKA; 06.03.2014 в 17:35.
Старый 06.03.2014, 18:52   #2  
RVS is offline
RVS
Сенбернар
Аватар для RVS
Злыдни
 
696 / 130 (6) +++++
Регистрация: 27.02.2003
Адрес: Королев МО
Уточните, пожалуйста, что там подразумевается под lalala. И зачем - exists join ?

Цитата:
Сообщение от IKA Посмотреть сообщение
X++:
exists join InventDim
      where lalala
----

Предварительный диагноз :

- по exists join вы одну и ту же PurchLine находите не один, а больше раз.
- поскольку весь цикл - внутри транзакции - при попытке повторно изменить запись (без reread()) - происходит тот самый update conflict

Вот как-то так
__________________
Best Regards,
Roman

Последний раз редактировалось RVS; 06.03.2014 в 18:55.
Старый 06.03.2014, 18:58   #3  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
1) каким образом exists может приводить к дупликатам???????
2) дело точно не в inventDim , тк в дебаггере видно. что разные записи purchLine выбираются
Старый 06.03.2014, 19:21   #4  
RVS is offline
RVS
Сенбернар
Аватар для RVS
Злыдни
 
696 / 130 (6) +++++
Регистрация: 27.02.2003
Адрес: Королев МО
Цитата:
Сообщение от IKA Посмотреть сообщение
1) каким образом exists может приводить к дупликатам???????
Условие "lalala" расшифруйте - тогда объясню, каким. Если может, конечно ))

Пока не вижу условия - могу только предполагать. Потоому и написал - "предварительный" диагноз )
__________________
Best Regards,
Roman
Старый 06.03.2014, 19:55   #5  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,907 / 5717 (196) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Попробуйте включить трассировку SQL и посмотреть (по сохраненному стеку вызовов) из какого куска кода реально идет обновление purchLine. Ваш purchLine.update() втихаря порождает вызов inventUpd_estimated, в котором много чего интересного происходит. Есть шансы что из за кастомизаций или из за какого-нить неаккуратно отключенного регионального функционала, этот код находит еще одну копию того же самого purchLine, меняет ее и обновляет. Когда после этого доходит дело до обновления в самом purchLine.update(), система начинает ругаться, потому что номер версии записи в переданном буфере и номер версии записи в БД - не совпадают.
За это сообщение автора поблагодарили: MikeR (10), S.Kuskov (2).
Старый 06.03.2014, 22:11   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от fed Посмотреть сообщение
этот код находит еще одну копию того же самого purchLine, меняет ее и обновляет.
Нет тогда бы purchLine.reread() не помог бы избежать конфликта, т.к. стоит в самом начале итерации. Обновляется другая запись, не та (или не только та) запись которая выбрана на текущей итерации, но тоже присутствующая в выборке.
За это сообщение автора поблагодарили: IKA (1).
Старый 07.03.2014, 12:06   #7  
RVS is offline
RVS
Сенбернар
Аватар для RVS
Злыдни
 
696 / 130 (6) +++++
Регистрация: 27.02.2003
Адрес: Королев МО
А почему бы не сделать "естественным образом"? Вот так, например :

X++:
ttsBegin;
     while select forupdate purchLine
    order by Confirmeddlv
    where purchLine.PurchId            == purchId 
        && purchLine.ItemId              == itemId  
        && purchLine.PurchStatus     == PurchStatus::Backorder 
        && ! purchLine.IsDeleted
    join inventDim
      where inventDim.InventDimId    == purchLine.InventDimId
        && lalala           
   {
         // Что-то делаем с purchLine

         purchLine.update();
    }
Просто, чтобы не запутывать Аксу излишне?

IKA, напишите, как решилось, пожалуйста. Случай странный, ИМХО )
__________________
Best Regards,
Roman
Старый 07.03.2014, 13:23   #8  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
А у вас случаем не активен чек активировать управление изменениями в параметрах модуля закупок и источников ?

Просто в стандарте в методе update строки покупки вшит код, который в некоторых случая при обновлении данных по одной строке запускает массовую обработку по всем строкам текущего заказа см. PurchLineType\updatePurchTable (строка с VersioningPurchaseOrder\change, там кстати вызов идет через doUpdate других строк).

Цитата:
А почему бы не сделать "естественным образом"?
А чем первый вариант то не естественен? Зачем тянуть данные из второго курсора если они не нужны?
__________________
Sergey Nefedov
За это сообщение автора поблагодарили: RVS (1), IKA (1).
Старый 07.03.2014, 14:36   #9  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
Если кому интересно, я накопала в чем проблема, вот ток как лечить - ума не приложу, тк мне кажется, это баг
Все дело в коде класса VersioningPurchaseOrder метод archivePurchLine, в самом конце вызывыается такое дело :
X++:
 purchLine.skipDataMethods(true);
    purchLine.skipDatabaseLog(true);
    update_recordset purchLine
        setting IsModified = NoYes::No
        where purchLine.PurchId == purchTable.PurchId
           && purchLine.IsModified
           && purchLine.InventTransId != skipInventTransId;
Все работает хорошо. если я это дело комменчу.
Дело в том,что мне кажется, это куски того, что должно вызываться при галке, упомянутой SRF , но 1) у нас она не стоит 2) в коде нет никаких проверок на какие-либо парметры и настройки (ну или я не вижу). Стек вызовов у меня такой
X++:
[s]    \Classes\VersioningPurchaseOrder\archivePurchLine                                                      99
[s]    \Classes\VersioningPurchaseOrder\archiveCurrentVersion                                                 28
[s]    \Classes\VersioningDocument\change                                                                     40
[s]    \Classes\VersioningPurchaseOrder\change                                                                26
[s]    \Classes\PurchLineType\updatePurchTable                                                                11
[s]    \Classes\PurchLineType\update                                                                          79
[s]    \Classes\PurchLineType_Purch\update                                                                    38
[s]    \Data Dictionary\Tables\PurchLine\Methods\update                                                       17
То есть, подтверждается теория S.Kuskov о том, что обновляется не тек запись, а другие, кот присутствуют в выборке.
Вопрос вечный : Кто виноват и что теперь делать???

Последний раз редактировалось IKA; 07.03.2014 в 14:53.
За это сообщение автора поблагодарили: Мартынов Дмитрий (1).
Старый 07.03.2014, 14:41   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
А чем не устраивает исходное решение - дергать внутри цикла purchLine.reread()?
Старый 07.03.2014, 14:42   #11  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
На всяк случай, значения параметров:
purchLineType.update(dropInvent, false, updateOrderLineOfDeliverySchedule) - здесь dropInvent = false, updateOrderLineOfDeliverySchedule = true

В purchLineType_Purch -> update вызов super(_dropInvent, _forceInterCompanyMirror, _updateOrderLineOfDeliverySchedule); , тут _dropInvent = false _forceInterCompanyMirror = false _updateOrderLineOfDeliverySchedule = true

Дальше все вызывается без параметров
Старый 07.03.2014, 14:51   #12  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Да, этот вызов я и имел ввиду. Он также может вызываться если у закупки статус Подтверждено, у вас в покупке этот статус, если да, попробуйте на какой нибудь у которой этот статус другой. Т.е. массово обновлять строки в покупке лучше до того момента пока эта покупка имеет статус до подтверждено. В стандарте есть ряд ключевых полей при изменении которых этот статус сбрасывается всегда, и потом требуется повторное подтверждение.
__________________
Sergey Nefedov

Последний раз редактировалось SRF; 07.03.2014 в 15:04.
Старый 07.03.2014, 14:51   #13  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
2gl00mie: Смысл писать в while select forupdate, если записи могут быть обновлены втихоря другой транзакцией?

Последний раз редактировалось IKA; 07.03.2014 в 14:56.
Старый 07.03.2014, 15:09   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Во-первых, в 2012-й для PurchLine по умолчанию включена OCC, так что forupdate и так не накладывает по умолчанию никаких блокировок в БД, во-вторых, с точки зрения СУБД это не другая транзакция, а ваша же собственная, в которой вы лопатите строки закупки. Просто в данной ситуации, образно говоря, правая рука не знает, что делает левая, но зато есть очень простое решение - перечитать запись перед обработкой, так почему бы этим решением не воспользоваться?
Старый 07.03.2014, 15:53   #15  
Stitch_MS is offline
Stitch_MS
Участник
Аватар для Stitch_MS
Соотечественники
 
397 / 478 (16) +++++++
Регистрация: 27.02.2006
Адрес: Дания
Цитата:
Сообщение от gl00mie Посмотреть сообщение
так почему бы этим решением не воспользоваться?
Я бы всё-таки предпочел выяснить, в какой момент запись обновляется извне, чтобы убедиться, что без reread никак, и спать спокойно. Хотя это может занять какое-то время.

Однажды с таким столкнулся, и исправил косяк в том, другом методе, так что reread не понадобился.
Старый 07.03.2014, 16:39   #16  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Выше приведен стек вызовов, показывающий, в какой момент запись обновляется "извне"
За это сообщение автора поблагодарили: Stitch_MS (1).
Старый 15.01.2016, 13:39   #17  
under_construction is offline
under_construction
Участник
 
2 / 10 (1) +
Регистрация: 04.04.2011
Подниму тему.
проблема в том, что не работает purchLine.skipDataMethods(true);
X++:
 purchLine.skipDataMethods(true);
    purchLine.skipDatabaseLog(true);
    update_recordset purchLine
        setting IsModified = NoYes::No
        where purchLine.PurchId == purchTable.PurchId
           && purchLine.IsModified
           && purchLine.InventTransId != skipInventTransId;
и вызывается purchLine.Update()
а вот в связи с чем он может не работать?
Старый 15.01.2016, 14:16   #18  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от under_construction Посмотреть сообщение
Подниму тему.
проблема в том, что не работает purchLine.skipDataMethods(true);
X++:
 purchLine.skipDataMethods(true);
    purchLine.skipDatabaseLog(true);
    update_recordset purchLine
        setting IsModified = NoYes::No
        where purchLine.PurchId == purchTable.PurchId
           && purchLine.IsModified
           && purchLine.InventTransId != skipInventTransId;
и вызывается purchLine.Update()
а вот в связи с чем он может не работать?
У меня не воспроизводится ни на 2009, ни на 2012.

Если речь про 2012, то
AOSAuthorization Property на таблице у вас случайно не настроен?
Тогда ещё .skipAosValidation() нужен будет
__________________
Zhirenkov Vitaly
Старый 15.01.2016, 16:26   #19  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Еще skipEvents() стоит попробовать - вдруг кто уведомления себе настроил.
За это сообщение автора поблагодарили: MikeR (5).
Старый 15.01.2016, 18:11   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от under_construction Посмотреть сообщение
в связи с чем он может не работать?
Вопрос про skipDeleteMethod
Теги
ax2012, ax2012r2

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX Sustained Engineering: Update conflict error thrown when an Intercompany Purchase Order is invoiced Blog bot DAX Blogs 0 15.12.2013 02:18
Dynamics AX Sustained Engineering: Update conflict error thrown when an Intercompany Purchase Order is invoiced Blog bot DAX Blogs 0 04.07.2013 08:11
fed: Net requirements update in MRP Module and Working Set of MRP Blog bot DAX Blogs 14 08.05.2012 13:09
emeadaxsupport: Synchronizing AX to Outlook Cannot edit a record in Activities (smmActivites) An update conflict occured Blog bot DAX Blogs 0 20.09.2011 23:12
An update conflict occurred due to another user process deleting the record or changing one or more fields in the record ideveloper DAX: Программирование 5 08.08.2011 18:52

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 03:13.