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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.06.2018, 08:08   #1  
iiipoizone is offline
iiipoizone
Участник
 
43 / 11 (1) +
Регистрация: 07.09.2015
CustTrans невозможно обновить
В CustTrans добавлены 2 поля.
Почему-то некоторые записи не возможно обновить.

X++:
static void fillCustTrans(Args _args)
{
    #avifiles
    CustInvoiceJour CustInvoiceJour;
    CustTrans custTrans;
    SysOperationProgress progress;
    int i,j;
    ;
    select count(recid) from custTrans where custTrans.Invoice != "" ;
    i = custTrans.RecId;
    progress = SysOperationProgress::newGeneral(#aviupdate, "Update", i);
    while select AmountCur10,AmountCur18,recid,Invoice,AccountNum,TransDate from custTrans
        where custTrans.Invoice != ""
     //   && custTrans.RecId == 5638268785
        {
            j++;

            progress.setText(strfmt("%1 from %2", j, i));
            progress.incCount();
            select firstonly TaxAmount10, TaxAmountStandart from CustInvoiceJour
                where CustInvoiceJour.invoiceId == custTrans.Invoice
                && CustInvoiceJour.InvoiceAccount == custTrans.AccountNum
                && CustInvoiceJour.InvoiceDate == custTrans.TransDate;
            custTrans.selectForUpdate(true);
            ttsbegin;//custTrans.ttsbegin();
            custTrans.AmountCur10 = CustInvoiceJour.TaxAmount10;
            custTrans.AmountCur18 = CustInvoiceJour.TaxAmountStandart;
            try
            {
                custTrans.doupdate(); // ошибка возникает здесь
            }
            catch
            {
                info(strfmt("%1",custTrans.RecId));
                ttsabort;
                continue;
            }
            ttscommit;//custTrans.ttscommit();
        }
}
на doUpdate возникает ошибка:

Невозможно отредактировать запись в Проводки по клиенту (CustTrans).
Возник конфликт обновления из-за того, что другой пользовательский процесс выполняет удаление записи или изменение одного или нескольких полей в записи.


Причем всегда по одному и тому же recId. База тестовая, на ней никто не работает.
Что можно сделать такое, чтобы обновить всю таблицу?

Последний раз редактировалось iiipoizone; 05.06.2018 в 08:11.
Старый 05.06.2018, 09:55   #2  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Кто ж вас так код форматировать учил?

Попробуйте
X++:
while select forUpdate custTrans
    where custTrans.Invoice
{
}
раз вы всеравно их обьновляете все.

AX нужно RecVersion, без него она не может понять обновляете ли вы то что выбрали ранее, а вы его не выбираете...

Последний раз редактировалось skuull; 05.06.2018 в 10:04.
За это сообщение автора поблагодарили: S.Kuskov (5), iiipoizone (1).
Старый 05.06.2018, 10:33   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Или после custTrans.selectForUpdate(true) нужно повторно перечитать запись custTrans.reread();
За это сообщение автора поблагодарили: iiipoizone (1).
Старый 05.06.2018, 11:21   #4  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Или после custTrans.selectForUpdate(true) нужно повторно перечитать запись custTrans.reread();
Это будет работать, но это тупо. Мы выбираем список полей, а потом реридом выбираем все поля еще раз. 2 запроса к БД, в чем смысл?

Последний раз редактировалось skuull; 05.06.2018 в 11:57.
Старый 05.06.2018, 12:44   #5  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от skuull Посмотреть сообщение
AX нужно RecVersion, без него она не может понять обновляете ли вы то что выбрали ранее, а вы его не выбираете...
Согласен, не хватает RecVersion.
Однако код совершенно не пригоден с точки зрения производительности:
  1. На кой здесь вообще прогресс нужен, если все это должно за пару секунд отработать?
  2. Транзакция должна быть внутри блока try.
  3. Лучше сделать while select forupdate вместо вызова selectForUpdate(true)
  4. Я подхожу к идее использовать update_recordset, если убрать всю лишнюю шелуху, не забыв при этом про skipDataMethods и skipDatabaseLog.
__________________
// no comments
Старый 05.06.2018, 13:25   #6  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от iiipoizone Посмотреть сообщение
Почему-то некоторые записи не возможно обновить.
Не некоторые, а все, что попали в фильтр по условию.
__________________
// no comments
Старый 05.06.2018, 13:35   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от skuull Посмотреть сообщение
Это будет работать, но это тупо. Мы выбираем список полей, а потом реридом выбираем все поля еще раз. 2 запроса к БД, в чем смысл?
Я понимаю. Поэтому и написал ИЛИ. В зависимости от задачи. Это может быть полезно например, чтобы избавиться от одной большой транзакции.
Ведь если ставить forupdate в запросе, то и транзакцию тогда открывать до цикла?

См. также forUpdate перед ttsbegin
Модификация огромного количества (сотни тысяч) записей в Axapta 3.0 SP4

Последний раз редактировалось S.Kuskov; 05.06.2018 в 13:49.
Старый 05.06.2018, 13:41   #8  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от iiipoizone Посмотреть сообщение
В CustTrans добавлены 2 поля.
Почему-то некоторые записи не возможно обновить.
(...)
Причем всегда по одному и тому же recId. База тестовая, на ней никто не работает.
Что можно сделать такое, чтобы обновить всю таблицу?
Причин может быть 2

Причина 1: Это фича (особенность) хранения данных MS SQL.

1. Если в запросе явным образом не указана опция Order By, то, в общем случае, порядок следования записей в выборке будет произвольным

Да, как правило, этот порядок будет совпадать с кластерным индексом. Но именно "как правило". Это именно "совпадение". Не гарантия

2. При внесении изменений в данные таблицы возможно (опять же, не обязательно. Возможно) перестроение индексов вообще и кластерных индексов в частности

Из этого следует, что, в общем случае, если внутри цикла выполняется изменение данных той таблицы, по которой выборка и выполняется, то возможно, что одна и та же запись таблицы внутри цикла while select может быть выбрана несколько раз

Для проверки этого предположения, выведите в infolog значения всех записей, которые попали в выборку и посмотрите, не повторяется ли одно и то же значение RecId несколько раз

На самом деле, такая ситуация является скорее исключением, чем правилом. Т.е. случается достаточно редко. Просто это надо иметь в виду. "Лечится" это двумя способами

1. Регулярное обновление (перестроение) индексов базы данных
2. Включение в цикл While select опции order By. Но! Обязательно по тем полям, которые не будет изменяться внутри цикла. В данном случае можно по RecId


Причина 2: Запись действительно была обновлена

Это зависит от версии Axapta и сделанных изменений. Дело в том, что doUpdate() не гарантирует того, что никакие сопутствующие методы не будут выполнены. Она лишь гарантирует, что не будет выполнен табличный метод Update().

Но изменения в запись могут быть внесены и другими методами. И вот в этом случае изменится значение RecVersion и Axapta посчитает, что запись была изменена другим процессом. В этом случае и требуется перезапрос Reread()

Посмотрите, нет ли у Вас на таблице CustTrans каких-либо связанных событий на методе update.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: iiipoizone (1).
Старый 06.06.2018, 07:27   #9  
iiipoizone is offline
iiipoizone
Участник
 
43 / 11 (1) +
Регистрация: 07.09.2015
Благодарю всех. надо было в Select добавить поле RecVersion
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Условия в запросе sql в аксапте user_ax DAX: Программирование 27 28.02.2013 11:03
CustTrans vs CustSettlement mvsenin DAX: Прочие вопросы 7 26.10.2012 02:14
Проблема с CustTrans Alexanderrrr DAX: Программирование 35 23.11.2009 10:43
Как в форме CustTrans через query отобрать записи у которых AmountCur != 0 ( когда в QueryBuildRange ставишь value(strFmt('!0')); - не работает!) rkorchagin DAX: Программирование 12 02.04.2007 17:58
при построении перекрёстных ссылок выдаётся сообщение об ошибках mmmax DAX: Программирование 10 21.01.2005 12:42

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

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

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