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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 22.01.2014, 09:44   #1  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Коллеги, что вы думаете о данном коде? 2MikeR
Цитата:
Сообщение от MikeR Посмотреть сообщение
Для AndyD DO NOT: Hold database locks for longer than is necessary.
DO: Limit the transaction scope by grabbing locks at the latest possible time and
releasing locks as early as possible.
Не могу отвечать в закрытой теме

Какое отношение это имеет к исходному вопросу?
По вашему, транзакция нужна только потому, что Аксапта иначе не дает апдейт сделать?
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: macklakov (1), S.Kuskov (2).
Старый 22.01.2014, 13:37   #2  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Цитата:
Сообщение от AndyD Посмотреть сообщение
Не могу отвечать в закрытой теме

Какое отношение это имеет к исходному вопросу?
По вашему, транзакция нужна только потому, что Аксапта иначе не дает апдейт сделать?
Там смысл именно в том, что бы обновлять другим способом, делать транзацию внутри цикла, а не во вне. Собственно об этом я тогда и писал, просто нашел подтверждение своим мыслям, вот и все.
__________________
Axapta book for developer
Старый 22.01.2014, 13:48   #3  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Для карсоты решения еще раз приведу утверждения

1 С чего все началось:
X++:
ttsbegin;
    WHILE(TRUE)
    {
        SELECT FIRSTONLY current WHERE current.InvGuid == InvGUID;
        InvGUID = current.ParentInvGUID;

        SELECT FIRSTONLY parent WHERE current.ParentInvGUID == parent.InvGUID;

        if(parent)
        {
            //parentDistr.disableCache();
            SELECT FIRSTONLY
            FORUPDATE parentDistr
            WHERE parentDistr.InvGUID == InvGUID &&
                parentDistr.TransRecId == inventoryGuidInvoice.TransRecId
                //...........
                && parentDistr.JuridicalPersonId == inventoryGuidInvoice.JuridicalPersonId;

            if(parentDistr)
            {
                parentDistr.AMOUNTCUR += inventoryGuidInvoice.AmountCur;//слияние к предку
                //.......
                parentDistr.Update();
            }
            else
            {
                parentDistr.data(InventoryGuidInvoice);
                parentDistr.InvGUID = parent.InvGUID;
                parentDistr.insert();
            }
        }
        else
        {
            break;
        }

        current.clear();
    }
    ttscommit;
2 Моя формулировка
X++:
while select
{
	ttsbegin;
	select forupdate 
	ttscommit;
}
3 Что гласит документация :
X++:
DO NOT: Hold database locks for longer than is necessary.
DO: Limit the transaction scope by grabbing locks at the latest possible time and
releasing locks as early as possible.
4 Не корректный код, читай в п1
X++:
ttsBegin; 
 
while select ItemId 
    from salesLine 
{ 
    select firstOnly forUpdate ItemType, ItemBuyerGroupId  
       from inventTable 
           where inventTable.ItemId == salesLine.ItemId; 
 
    If (inventTable && (inventTable.ItemType == InventItemType::Item)) 
    { 
         inventTable.ItemBuyerGroupId = ; 
         inventTable.update(); 
    } 
} 
 
ttsCommit;
5 Корректный код
X++:
while select ItemId 
    from salesLine 
{ 
    select firstOnly forUpdate ItemType, ItemBuyerGroupId  
       from inventTable 
           where inventTable.ItemId == salesLine.ItemId; 
 
    If (inventTable && (inventTable.ItemType == InventItemType::Item)) 
    { 
        ttsBegin; 
        inventTable.ItemBuyerGroupId = ; 
        inventTable.update(); 
        ttsCommit; 
    } 
}
__________________
Axapta book for developer
Старый 22.01.2014, 13:51   #4  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Собственно написал, что бы было понятно ищущим знаний коллегам.
__________________
Axapta book for developer
Старый 22.01.2014, 14:00   #5  
ackid is offline
ackid
Участник
 
34 / 12 (1) ++
Регистрация: 21.10.2013
Я считаю что при необходимости вполне можно транзакцию вне цикла открывать... но вот потенциально бесконечный цикл....блин...как вижу этот true так в дрожь))))
За это сообщение автора поблагодарили: MikeR (2).
Старый 22.01.2014, 14:13   #6  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
MikeR, в ваших примерах из п. 4 и 5 идет обработка плоских данных, для которых отмена части транзакций не критична, ибо они могут быть выполнены позже простым повторным запуском того же кода. А в исходном алгоритме (п. 1) идет обход узлов дерева, причем выполняется операция +=. Если такой обход раздробить на мелкие транзакции, то при их частичном откате восстановить целостность данных будет невозможно физически (если явно не хранить историю обновления).
Ну а пример из п. 2 (while select...) неприменим для обхода дерева при заданной в п.1 структуре данных.
Наверное это вам и пытаются сказать...
PS: С тем, что п.5 более корректен в общем случае, чем п.4 - согласен.
__________________
Старый 22.01.2014, 16:34   #7  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Цитата:
Сообщение от Ruff Посмотреть сообщение
Наверное это вам и пытаются сказать...
.
Что сказали, то сказали, бумага все стерпит.
С плоскими разобрались, так понимаю. НО ДАЖЕ в иерархической реализации это дает результат. Представляете если это достаточно большой пул проводок. Все напрочь блокируется, а какова вероятность, что произойдет исключительная ситуация? На практике это менее 5 процентов. Что стоит каждый раз терпеть блокировки или тупо следовать надуманной целостности, которая даже еще и не думала нарушаться...
Не говоря о том, что по мелочам
1)
X++:
        SELECT FIRSTONLY current WHERE current.InvGuid == InvGUID;
        InvGUID = current.ParentInvGUID;

        SELECT FIRSTONLY parent WHERE current.ParentInvGUID == parent.InvGUID;
спокойно сливается в одни запрос
2)
X++:
parentDistr.AMOUNTCUR += inventoryGuidInvoice.AmountCur;//слияние к предку
легко используется агрегатная функция.
__________________
Axapta book for developer
Старый 22.01.2014, 19:46   #8  
ax_mct is offline
ax_mct
Banned
 
2,548 / 1091 (0) ++++++++
Регистрация: 10.10.2005
Адрес: Westlands
Цитата:
Сообщение от MikeR Посмотреть сообщение

5 Корректный код
X++:
while select ItemId 
    from salesLine 
{ 
    select firstOnly forUpdate ItemType, ItemBuyerGroupId  
       from inventTable 
           where inventTable.ItemId == salesLine.ItemId; 
 
    If (inventTable && (inventTable.ItemType == InventItemType::Item)) 
    { 
        ttsBegin; 
        inventTable.ItemBuyerGroupId = ; 
        inventTable.update(); 
        ttsCommit; 
    } 
}
И все же насколько обоснованно выбирать буфер для обновления (forUpdate) ВНЕ транзакции (ttsbegin…ttscommit)? Типа код оптимизирован для уменьшения блокировок путем перемещения tts* ?
Что мешает при той же оптимизации выбирать внутри транзакции? Не знаю, у меня глаза режет от такого.
Почему бы не так:
X++:
while select ItemId 
    from salesLine 
{ 
    select firstOnly ItemType, ItemBuyerGroupId  
       from inventTable 
           where inventTable.ItemId == salesLine.ItemId; 
 
    If (inventTable && (inventTable.ItemType == InventItemType::Item)) 
    { 
        ttsBegin; 
        [B]inventTable.forupdate(true);[/B]
        inventTable.ItemBuyerGroupId = ; 
        inventTable.update(); 
        ttsCommit; 
    } 
}
Я возможно не прав, но глаза
Старый 22.01.2014, 21:22   #9  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Цитата:
Сообщение от ax_mct Посмотреть сообщение
Что мешает при той же оптимизации выбирать внутри транзакции?
Согласен, но это уже совсем мелкие детали.

Странно, что никто не заметил, что нет филд листа (тоже сорри за американизм/англицизм), слияния запросов, агрегирующей функции, но это тоже семечки, но на больших таблицах семечки уже серьезные. По while(true) и целостности вообще смотрю целая группировка даже существует.
__________________
Axapta book for developer

Последний раз редактировалось MikeR; 22.01.2014 в 21:29.
Старый 23.01.2014, 12:04   #10  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от MikeR Посмотреть сообщение
Для карсоты решения еще раз приведу утверждения

5 Корректный код
X++:
while select ItemId 
    from salesLine 
{ 
    select firstOnly forUpdate ItemType, ItemBuyerGroupId  
       from inventTable 
           where inventTable.ItemId == salesLine.ItemId; 
 
    If (inventTable && (inventTable.ItemType == InventItemType::Item)) 
    { 
        ttsBegin; 
        inventTable.ItemBuyerGroupId = ; 
        inventTable.update(); 
        ttsCommit; 
    } 
}
Вот до кучи еще вариант: (без всяких ttsbegin вообще)
X++:
while select ItemId 
    from salesLine
join inventTable
where inventTable.itemid == salesLine.itemId &&
inventTable.ItemType == InventItemType::Item  
{ 
        update_recordset inventTableUpd
        setting inventTableUpd.ItemBuyerGroupId = 
        where inventTableUpd.ItemId == salesLine.ItemId;
}
Кстати к вопросу о производительности БД. Множество ttsbegin --> ttscommit не всегда лучший вариант для производительности БД.

Объединение множественных обновлений в одну транзакцию - это конечно блокировки - но более производительный вариант для БД ИХМО.

Последний раз редактировалось someOne; 23.01.2014 в 12:09.
За это сообщение автора поблагодарили: mazzy (2), MikeR (3).
Старый 23.01.2014, 13:17   #11  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
someOne хороший варинат, если покурсовый не перекрыт.
__________________
Axapta book for developer
Старый 23.01.2014, 13:58   #12  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,430 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от someOne Посмотреть сообщение
Вот до кучи еще вариант
А в чем профит от использовании групповой операции применительно к одной записи?
Старый 23.01.2014, 14:08   #13  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,895 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
А в чем профит от использовании групповой операции применительно к одной записи?
Один запрос к SQL Server вместо двух...
За это сообщение автора поблагодарили: S.Kuskov (1).
Старый 22.01.2014, 14:44   #14  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
тут вся загвоздка в слове necessary - устраивает ли тебя если в случае проблем с сетью половина строк обновится, а половина, нет
За это сообщение автора поблагодарили: macklakov (1), MikeR (5).
Старый 22.01.2014, 15:58   #15  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от belugin Посмотреть сообщение
тут вся загвоздка в слове necessary - устраивает ли тебя если в случае проблем с сетью половина строк обновится, а половина, нет
Или - готов ли ты поставить всю систему в интересную позу на продолжительное время блокировками на время обновления в одной транзакции и (если не срастется) повторять пока не получится
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: MikeR (2).
Старый 22.01.2014, 16:18   #16  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Vadik Посмотреть сообщение
Или - готов ли ты поставить всю систему в интересную позу на продолжительное время блокировками на время обновления в одной транзакции и (если не срастется) повторять пока не получится
Об этом тоже стоит подумать, но о целостности забывать не надо если разбиение на транзакции нарушает целостность надо вводить какие-то дополнительные структуры для того, чтобы она не нарушалась.
Старый 22.01.2014, 19:47   #17  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от belugin Посмотреть сообщение
Об этом тоже стоит подумать, но о целостности забывать не надо если разбиение на транзакции нарушает целостность надо вводить какие-то дополнительные структуры для того, чтобы она не нарушалась.
Давайте для экономии времени будем исходить из того что разработчик по умолчанию знает что в данном случаем является минимальным скопом для транзакции (прошу прощения за англицизмы) и спор лишь о том стоит ли стараться придерживаться его в разработке или писать "как проще" - "ttsbegin в первой строке, ttscommit в последней" Я как человек который в итоге отвечает за весь инстанс в целом привык требовать чтобы код оттестированный в разработческой среде можно было запускать в продуктиве без переписывания (мелкие транзакции), бог весть чего в последний момент "наоптимизируют", но готов выслушать альтернативные точки зрения
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: mazzy (2).
Старый 23.01.2014, 09:40   #18  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Vadik Посмотреть сообщение
Давайте для экономии времени будем исходить из того что разработчик по умолчанию знает что в данном случаем является минимальным скопом для транзакции
Давайте исходить из предложенного примера. MikeR,
- что произойдет, если нерадивый админ кильнет aos32 на середине процесса обновления таблицы? (случится креш аоса, пропадение связи и прочее - кстати, код на сервере выполняется?)
- что произойдет если два пользователя запустят этот процесс одновременно
- используется ли на изменяемой таблице оптимистичная или пессимистичная блокировка и как измениться поведение "совсем уж мелких деталей" при этом.

P.S. По моему опыту есть некий оптимум по скорости обновления записей и он может находиться где-то между "все записи сразу" и "каждая запись отдельно". Т.е. может быть более выгодно обновлять пакетами по n записей.
Старый 22.01.2014, 17:43   #19  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,895 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Гм. Вы бы ссылочку на оригинальную тему дали, а то народ что-то ожесточенно обсуждает, а начала не видно...
Старый 22.01.2014, 18:18   #20  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Цитата:
Сообщение от fed Посмотреть сообщение
Гм. Вы бы ссылочку на оригинальную тему дали, а то народ что-то ожесточенно обсуждает, а начала не видно...
Я бы добавил : "сражается не на жизнь, а на смерть..."
__________________
Axapta book for developer
Теги
базовая информация, транзакции

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Коллеги, что вы думаете о данном коде? MikeR DAX: Программирование 36 21.01.2014 19:38
Странное поведение при закрытии склада-ошибка в коде? Aquarius DAX: Программирование 11 27.06.2013 13:37
.NET business connector не видит изменений в коде Аксапты rkorchagin DAX: Программирование 2 22.01.2010 11:43
Нужно сделать выборку из нескольких таблиц (в данном случае из четырех). niktata DAX: Программирование 10 30.09.2008 09:42
Можно ли в коде управлять свойством Mandatory? kostas DAX: Программирование 5 10.03.2004 11:14

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

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

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