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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.12.2020, 16:06   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
ax2012: UnitOfWork.getByKey(): а как получить запись forUpdate?
UnitOfWork.getByKey(record): а как получить запись в режиме forUpdate?

если getByKey возвращает true, то в record содержится запись.
Но record.selectForUpdate() у меня всегда возвращает false.

Как сделать так, чтобы полученную из getByKey можно было обновить методом update, не выполняя повторного поиска.

Я правильно понимаю, что начав использовать UnitOfWork, мы должны использовать только его? Ну, или выполнять повторный поиск в базе?
__________________
полезное на axForum, github, vk, coub.
Старый 08.12.2020, 18:22   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от mazzy Посмотреть сообщение
...Но record.selectForUpdate() у меня всегда возвращает false.

Как сделать так, чтобы полученную из getByKey можно было обновить методом update, не выполняя повторного поиска.

Я правильно понимаю, что начав использовать UnitOfWork, мы должны использовать только его? Ну, или выполнять повторный поиск в базе?
Может что-то типа такого
\Classes\InventCostItemDim\updateInventTrans
X++:
protected void updateInventTrans(InventTrans _inventTrans)
{
    if (_inventTrans.RecId)
    {
        _inventTrans.skipTTSCheck(true); // !!!
        this.updateCostAmountStd(_inventTrans);
        _inventTrans.update(); // !!!
    }

    this.updateInventTransMap(_inventTrans);
}
В закрытии склада буфер доставали из мапа, т.е. никакого курсора с ним не связано, просто структура в памяти с полями. И процитированным способом он успешно обновлялся в БД без перевыбора записи. Но, если мне не изменяет память при заполнении мапа с InventTrans, запись выбиралась forUpdate c наложением блокировки в БД.


Хотя возможно для UnitOfWork возможен другой подход.
Старый 08.12.2020, 19:34   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Logger Посмотреть сообщение
Может что-то типа такого

В закрытии склада буфер доставали из мапа
Не.
В мапе хранится ссылка на исходный объект, который был получен обычными поиском с forUpdate.
А вот getByKey() сам выполняет поиск. причем, похоже без указания forupdate (или я чего-то не понимаю)




Про ссылки:
Что передается функциям, ссылки или значения?
Что хранит map ? ссылки на Record или сам рекорд в упакованном виде ?

https://www.youtube.com/watch?v=nmoB6dzJC7o
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 08.12.2020 в 19:44.
Старый 08.12.2020, 20:17   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Набросал небольшое исследование.
В общем из мапа достается равная копия буфера несвязанная с курсором.
Хотя почему-то в моем случае она обновилась и без skipTtsCheck
Неожиданно.

X++:
static void testBuffer(Args _args)
{
    // RecId           recId = 5637144576;
    InventTable     inventTable;
    InventTable     inventTable2;
    
    Map             map = new Map(Types::Int64, Types::Record);
    ;
    
    // inventTable.disableCache(true);
    ttsBegin;
    
    // inventTable = InventTable::findRecId(recId, curExt2dataareaid(tableNum(InventTable)), true);
    select 
    forupdate 
    inventTable order by RecId;
    
    info(strFmt("до помещения в мап inventTable.usageCount() = %1", inventTable.usageCount()));
    info(strFmt("recId = %1, forUpdate = %2", inventTable.RecId, inventTable.selectForUpdate())); // выдаст true
    
    map.insert(inventTable.RecId, inventTable);
    info(strFmt("после помещения в мап inventTable.usageCount() = %1", inventTable.usageCount()));
    
    inventTable2 = map.lookup(inventTable.RecId);
    info(strFmt("Достали из мапа recId = %1, forUpdate = %2", inventTable2.RecId, inventTable2.selectForUpdate())); // выдаст false
    
    if (inventTable2.equal(inventTable))
    {
        info(strFmt("Буфер извлеченный из БД и из мапа РАВНЫ. inventTable.usageCount() = %1, inventTable2.usageCount() = %2", inventTable.usageCount(), inventTable2.usageCount()));
    }
    else
    {
        info(strFmt("Буфер извлеченный из БД и из мапа НЕ равны.inventTable.usageCount() = %1, inventTable2.usageCount() = %2", inventTable.usageCount(), inventTable2.usageCount()));
    }
    
    inventTable.RecId++;
    
    if (inventTable2.RecId == inventTable.RecId)
    {
        info("в памяти это один и тот же объект");
    }
    else
    {
        info("в памяти это разные объекты");
    }
    
    // а что с курсором ?
    
    try
    {
        next inventTable;
        info(strFmt("С буфером извлеченным из базы связан курсор и можно выполнить next. - Извлечена следующая запись с RecId = %1", inventTable.RecId));
    }
    catch
    {
        info(strFmt("С буфером извлеченным из базы уже НЕ связан курсор (и это странно) RecId = %1", inventTable.RecId));
    }
    
    /* // если раскомментить код то будет ошибка времени выполнения что говорит о том что курсор уже не связан с inventTable2 т.е. мы работали с копией 
    try
    {
        next inventTable2;
        info(strFmt("С буфером извлеченным из базы связан курсор и можно выполнить next. - Извлечена следующая запись с RecId = %1", inventTable2.RecId));
    }
    catch
    {
        info(strFmt("С буфером извлеченным из базы уже НЕ связан курсор (и это странно) RecId = %1", inventTable2.RecId));
    }
    */
    
    info(strFmt("RecId = %3. inventTable.BOMLevel до обновления = %1. forupdate = %2", inventTable.BOMLevel, inventTable.selectForUpdate(), inventTable.RecId));
    inventTable.BOMLevel++;
    inventTable.doUpdate();
    inventTable.reread();
    info(strFmt("inventTable.BOMLevel после обновления = %1", inventTable.BOMLevel));
    
    info(strFmt("RecId = %3. inventTable2.BOMLevel до обновления = %1. forupdate = %2", inventTable2.BOMLevel, inventTable2.selectForUpdate(), inventTable2.RecId));
    inventTable2.BOMLevel++;
    inventTable2.doUpdate();
    inventTable2.reread();
    info(strFmt("inventTable2.BOMLevel после обновления = %1", inventTable2.BOMLevel, inventTable.RecId));
    // оказалось что skipTtsCheck уже не нужен
    
    ttsCommit;
    
}
За это сообщение автора поблагодарили: mazzy (15), SHiSHok (4).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
stephenmann: Technical History of Dynamics AX - From Axapta 3.0 to AX2012 Blog bot DAX Blogs 5 03.03.2017 10:22
ax2012 - почему не находит по RecID УЖЕ существующую запись? mazzy DAX: Программирование 14 21.11.2014 10:20
как получить активную запись грида dreamer DAX: Программирование 1 23.03.2007 14:58
Как получить запись из связанного DataSource (InnerJoin) Berty Wooster DAX: Программирование 1 17.09.2003 20:04

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

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

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