|
28.02.2018, 08:37 | #1 |
Участник
|
Update курсора таблицы, полученного из контейнера, не действует
Добрый день. Написан следующий абстрактный код:
X++: //объявления всех используемых переменных //... ttsbegin; select forupdate * from telegram where telegram.RecId == 5637147106; telegram.Sign += '-'; telegram.update(); ttscommit; НО(!) есть и такой код: X++: //объявления всех используемых переменных //... ttsbegin; select forupdate * from telegram where telegram.RecId == 5637147106; //Помещаем курсор таблицы в контейнер telegramCon = conins(telegramCon, 1, telegram); //... забываем на время... //... //вспоминаем, достаем обратно telegram = conpeek(telegramCon, 1); telegram.Sign += '-'; telegram.update(); ttscommit; Почему, господа? |
|
28.02.2018, 09:13 | #2 |
Участник
|
Копайте в сторону orig() и места выполнения вашего кода (клиент/сервер)
Ядро при обновлении записи сраанивает текущие значения и orig() значения и различия сбрасывает в базу. Для некоторых сценариев работы orig() был всегда равен самому буферу. Поэтому update ничего не обновлял. Вероятно это ваш случай. Можете еще посмотреть как устроено обновление InventTrans в пересчете себестоимости/закрытии склада. Там сделано похоже на ваш пример, но еще дергается skipTtsCheck() и.т.п. |
|
|
За это сообщение автора поблагодарили: gl00mie (2). |
28.02.2018, 09:31 | #3 |
Участник
|
Место выполнения - сервер, абстрактный код тестируется в джобе, а это точно, я полагаю, не клиент
Цитата:
Дело в использовании контейнера, однозначно. При десериализации, видимо что-то происходит... Кстати, когда курсор обратно получается из контейнера - в дебаггере видно, что "forupdate" утрачивается, приходится делать принудительно selectForUpdate(true)... но и без forupdate, как ни странно, не бросается исключение "запись не выбиралась для обновления"... в общем, чудеса в решете |
|
28.02.2018, 09:40 | #4 |
Участник
|
см.
\Classes\InventCostItemDim\updateInventTrans и все места где он используется. Там все работает. |
|
28.02.2018, 09:50 | #5 |
Участник
|
Цитата:
X++: protected void updateInventTrans(InventTrans _inventTrans) { ; if (_inventTrans.RecId) { _inventTrans.skipTTSCheck(true); this.updateCostAmountStd(_inventTrans); _inventTrans.update(); } if (mapInventTrans) mapInventTrans.insert(_inventTrans.RecId, _inventTrans); } |
|
28.02.2018, 10:14 | #6 |
Участник
|
А зачем это принципиальное использование контейнера? Я всегда пользовался map как в updateInventTrans и небыло проблем. Контейнер же для value типов, а запись она такая особенная
|
|
28.02.2018, 10:21 | #7 |
Участник
|
стоит попробовать, спасибо
В общем, не помог map Последний раз редактировалось Vasiliusis; 28.02.2018 в 10:27. |
|
28.02.2018, 10:47 | #8 |
Участник
|
Ну, Вам же уже сказали, что проблема в orig(). Простейший тест покажет проблему
X++: custTable custTable; custTable custTableOrig; Container conValue; select firstonly custTable; conValue = conIns(conValue, 1, custTable); custTable = null; // А теперь смотрим, что у нас в контейнере custTable = conPeek(conValue, 1); custTableOrig = custTable.orig(); info(strFmt('custTable.RecId = %1', custTable.RecId)); info(strFmt('custTableOrig.RecId = %1', custTableOrig.RecId)); Соответственно, если Вы все-равно хотите использовать контейнер, то после извлечения из него записи надо через buf2buf() скопировать набор "скаляров" в поля реальной записи. Ну, как-то так X++: custTableCon = conPeek(conValue, 1); select firstonly forupdate custTable where custTable.RecId == custTableCon.RecId; global::buf2buf(custTableCon, custTable);
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
28.02.2018, 11:09 | #9 |
Участник
|
Была такая идея, но я посчитал ее чересчур неспортивной... видимо, другого выхода нет, спасибо
|
|
28.02.2018, 11:21 | #10 |
Участник
|
Как уже сказали выше - поводом является отсутствие orig().
причиной является то, что в контейнер аксапта (версии 2009 и младше, 2012 без CIL) запоминает не ссылку на объект, а сериализованную строку. причем в контейнер сериализуются не все аспекты record, а только поля записи. Подозреваю, что не сериализуются приватные поля record-объекта. В том числе буфер, который используется для orig(). в 2012 CIL и выше в качестве контейнера используется системный Array<Object>. Поэтому такой проблемы быть не должно пока не будет происходить явная сериализация через sysLastValue или подобное. кстати, в 2012 CIL были замечены странные эффекты "переходного периода" - иногда работает так, а иногда иначе. в акс7 контейнер - всегда массив объектов, хранящий ссылки. кстати 2: контейнер в акс2012 и младше - не мутабельный объект. контейнер всегда пересоздается при любой правке контейнера. а точно ЛЮБОЕ изменение приводит к пересозданию контейнера? даже conpoke? Поэтому, например, KeySum - антипаттерн в младших версиях и вполне терпимая штука, начиная с 2012 CIL. Постарайтесь использовать меньше операций по модификации контейнера Последний раз редактировалось mazzy; 28.02.2018 в 11:24. |
|
|
За это сообщение автора поблагодарили: user_ax (2), Logger (3). |
01.03.2018, 06:46 | #11 |
Мрачный тип
|
Регулярно вижу такую рекомендацию на предмет "кабы чего не вышло".
Была в AOT ( вплоть до 2012-й, за еретическую и богопротивную 7-ку не знаю) такая map'а, LogMap кличется, и есть у этой map'ы метод, setData() называется. Занимаются там компоновкой контейнера состояния записи для разных системных журналов (в 2009-й - для журнала БД, журнала оповещений и какого-то еще "шлака" по эстонской функциональности) - т.е. дёргается оно на исполнение, мягко говоря, не так уж и редко. Люди, писавшие в упомянутом методе упомянутого объекта на слое SYS наполнение контейнера путем цикличной модификации исходного контейнера оператором "+=", в курсе этих рекомендаций ?
__________________
Мы летаем, кружимся, нагоняем ужасы ... |
|
01.03.2018, 07:39 | #12 |
Участник
|
|
|
28.02.2018, 14:10 | #13 |
Участник
|
Извините, а зачем вообще в контейнер пихать рекорд? Почему бы не положить recid и сделать в дальнейшем дополнительный find. Так точно будет работать. Или интересно поискать особенности работы ядра аксапты?) Map, list - будут получше, как уже выше писали про проводки складские.
Сергей, спасибо за информацию про контейнеры, увлекательно, плюсую |
|
Теги |
container, update, курсор, не работает |
|
|