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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.01.2007, 14:58   #1  
PavelX is offline
PavelX
MCTS
MCBMSS
 
46 / 97 (4) ++++
Регистрация: 08.09.2006
Адрес: Красноярск
Цикл, ttsabort и continue
Всем привет!

Столкнулся с такой проблемой (может она обсуждалась уже, но я что то не нашел). Выбираю в цикле while select записи таблицы ProjTable. Там же в цикле после проверки некоторого условия откатываю транзакцию и хочу перейти на следующую строку ProjTable в цикле. Но после вызова continue следующая строка не выбирается. То есть цикл как и положено проходит снова, но курсор ProjTable указывает на ту же самую запись, что и при первом проходе.

Для наглядности написал джоб который описывает данную ситуацию. Причем если цикл дополнить условием по projId (while select projT where projT.projId == "ИД_Проекта"), то continue работает нормально.



X++:
static void Test_TTS_Continue(Args _args)
{
    ProjTable               projT;
    int i = 0;
    ;
    ttsbegin;
while select projT 
//    while select projT where projT.projId == "ИД_Проекта"
    {
        info(int2str(i) + ',    projId = ' + projT.ProjId);
        i++;
        if (i>100)
            return;
        ttsabort;
        ttsbegin;
        continue;
    }
    ttscommit;
}
Что это? Глюк или я чего то не понимаю и так задумано? Если кто сталкивался или хотя бы знает как это обойти, поделитесь пожалуйста.

Заранее благодарен.

Последний раз редактировалось PavelX; 12.01.2007 в 15:01.
Старый 12.01.2007, 15:52   #2  
Russland is offline
Russland
MCTS
Аватар для Russland
MCBMSS
 
267 / 116 (4) +++++
Регистрация: 17.10.2005
Адрес: Донеччина, Україна
Цитата:
Там же в цикле после проверки некоторого условия откатываю транзакцию
и где же это "некоторое условие"?
не
X++:
if (i>100)
же?
__________________

В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню
Старый 12.01.2007, 15:56   #3  
Roman777 is offline
Roman777
NavAx
Аватар для Roman777
NavAx Club
 
320 / 64 (3) ++++
Регистрация: 10.02.2005
Адрес: г. Москва
Вообще в x++ не рекомендуется использование ttsabort и открытие/закрытие одной транзакции на разных уровнях вложенности.
Старый 12.01.2007, 16:47   #4  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Давайте подумаем вместе.
- Открыли транзакцию
- Открыли курсор
- Получили результат в несколько строк (fetch)
- Закрыли транзакцию
- Открыли транзакцию
- Захотели получить еще данные из курсора (fetch)

Что должен ответить SQL-сервер?
Старый 12.01.2007, 23:30   #5  
Torin is offline
Torin
Участник
 
127 / 31 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
Скорее всего, требовался уровень изоляции READ_COMMITED - он в Аксапте устанавливается только под транзакциями . А закрывают и открывают опять - чтобы меньше сталкиваться на блокировках.
Вообще, нехорошо так делать, если в цикле очень много проходов, с точки зрения СУБД.
Старый 13.01.2007, 12:28   #6  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Здесь получается такая схема работы.

1. Открыли транзакцию
2. Открыли курсор
3. Получили результат в несколько строк (fetch)
4. Закрыли транзакцию
5. Закрыли курсор
6. Открывается и закрывается транзакция несколько раз. Пока в буфере на клиенте есть записи - запросы на получение данных не идут.
7. Как только на клиенте закончились записи в буфере - переходим к пункту 2


При такой схеме легко попасть в бесконечный цикл, если нет дополнительных условий для его прерывания
Очень многое зависит от количества записей, получаемом при выборке (фетче) (при этом надо учесть, что это не константа и может отличаться для первой и последующих, а так же зависит от опций в select'е, например, firstfast).
Если количество записей в результате выборки меньше размера буфера (в данном случае, упрощая, это кол-во строк в нем помещающихся), то цикл отработает (в исходном вопросе при наложении условия в where так и происходит).
Если количество записей больше или равно размеру буфера, то попадаем в бесконечный цикл, в котором с какой-то периодичность записи будут повторяться

В общем, так делать - себе дороже.

2 PavelX

Расписали бы вы полнее задачу.
Но первое подложение сделаю - используйте UserConnection для вашей выборки (или для операций по изменению данных)
X++:
static void Test_TTS_Continue(Args _args)
{
    ProjTable               projT;
    int i = 0;
    UserConnection conn = new UserConnection();
    ;
    projT.setConnection(conn);
    ttsbegin;
while select projT 
//    while select projT where projT.projId == "ИД_Проекта"
    {
        info(int2str(i) + ',    projId = ' + projT.ProjId);
        i++;
        if (i>100)
            return;
        ttsabort;
        ttsbegin;
        continue;
    }
    ttscommit;
}
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: kashperuk (2), PavelX (1).
Старый 13.01.2007, 12:35   #7  
PavelX is offline
PavelX
MCTS
MCBMSS
 
46 / 97 (4) ++++
Регистрация: 08.09.2006
Адрес: Красноярск
2 Russland:
Не, условие конечно не это. Этот джоб я вообще написал чтоб показать в чем проблема. Просто когда я его запускаю у себя, цикл зацикливается притом, что значение projT остается одним и тем же. Вот я и хотел узнать у меня только так или это у всех.

2 Wamr:
Да, видимо для SQL-сервера такая конструкция равносильна новому запросу. Просто как то это неочевидно еще пока для меня, мало опыта в аксапте...

В понедельник попробую вынести while select за транзакцию, о результатах сообщу.
Старый 13.01.2007, 13:13   #8  
PavelX is offline
PavelX
MCTS
MCBMSS
 
46 / 97 (4) ++++
Регистрация: 08.09.2006
Адрес: Красноярск
Ситуация следующая:
Есть модуль расчета процентов и комиссионных по займам. Проекты это займы. Каждый проект верхнего уровня (родительский) - это займы у конкретного заимодателя, все его подпроекты - это займы определенных клиентов у этого заимодателя. Данный цикл используется в классе разноски платежей по займам по заимодателям. То есть этот цикл выполняется по родительским проектам (while select ProjT where ProjT.ParentId == ""), и за каждый проход разносит платежи по одному заимодателю. Всего таких проходов не много, порядка 10-15. Параллельно разноске в этом же цикле вызываются классы рассчета суммы комиссий и удержаний. Так вот при условии, что если сумма всех платежей по данному заимодателю будет меньше суммы комиссии, то такие платежи нужно отложить. Все дело в том что с налету вычленить расчет суммы комиссий и платежей из кучи классов разноски представилось проблематичным, я решил просто выполнять проверку этого условия в конце цикла и если она не проходила то отменять транзакцию. Понятно что это далеко не лучший вариант...

2 AndyD:
Спасибо за наводку, в понедельник попробую

ЗЫ. Прошу прощения если спутанно объяснил.

Последний раз редактировалось PavelX; 13.01.2007 в 13:19.
Старый 15.01.2007, 07:11   #9  
PavelX is offline
PavelX
MCTS
MCBMSS
 
46 / 97 (4) ++++
Регистрация: 08.09.2006
Адрес: Красноярск
Всем огромное спасибо за помощь, в особенности AndyD. С UserConnection все заработало .

Последний вопрос, при использовании UserConnection много подводных камней можно ожидать? и каких?
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как организовать цикл exodus DAX: Программирование 1 21.11.2007 10:50
Складская аналитика. Авторезервирование. Бесконечный цикл. andenis DAX: Функционал 8 27.06.2007 08:12
простейший job уходит в бесконечный цикл Keen DAX: Программирование 6 17.02.2007 21:32
ttsabort - как вернуть первоначальные данные? Damn DAX: Программирование 6 19.05.2004 11:32
Could not continue scan with NOLOCK due to data movement. ddadream DAX: Функционал 7 17.11.2003 11:36

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

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

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