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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.11.2011, 09:40   #1  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
? Кто использовал RecId
Доброе утро!

Вчера на рабочей базе появились отрицательные RecId -620715238, хотя за день до этого RecId был в районе 1367137064.

Хотелось бы узнать - есть ли способы узнать на какие таблицы были сгенерированы RecId?

Также интересуют особенности работы с отрицательными RecId. Про кратность 256 прочитал.

Спасибо!
Ax 3.0 SP3
Старый 25.11.2011, 09:46   #2  
egorych is offline
egorych
Участник
Самостоятельные клиенты AX
Oracle
 
761 / 154 (7) ++++++
Регистрация: 09.11.2006
Адрес: Краснодарский край
У нас уже 2 года отрицательные и ничего!
В чем может быть проблема? Ну только если сортировку делать по RecID и попадутся вместе отрицательные и положительные - но, я думаю, в здравом уме никто так не делает. Более причин для беспокойства не вижу.
__________________
Axapta 3.0 sp - хз какой, kr2
Старый 25.11.2011, 09:58   #3  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от egorych Посмотреть сообщение
У нас уже 2 года отрицательные и ничего!
В чем может быть проблема? Ну только если сортировку делать по RecID и попадутся вместе отрицательные и положительные - но, я думаю, в здравом уме никто так не делает. Более причин для беспокойства не вижу.
Понятно. У меня беспокойство вызывает нелинейное выделение RecId:

24.11.2011 12:40:38 1367133505
24.11.2011 12:40:51 -1774993986
24.11.2011 13:53:05 -622100572

В первой записи до предела оставался еще миллиард записей.
Старый 25.11.2011, 10:46   #4  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Импорт делал?

Георгий
Старый 25.11.2011, 11:19   #5  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от George Nordic Посмотреть сообщение
Импорт делал?

Георгий
Нет - не ровном месте скакнуло.
Подозрения 2:
1. Какая-то операция в Аксапте мгновенно отъела миллиард RecId за 13 секунд.
2. Возникли блокировки SYSTEMSEQUENCES и счетчик каким-то образом сбился на отрицательные значения.

Сейчас вопросы:
1. Что могло вызвать такой скачек?
2. Поможет ли дефрагментация вернуться к прежней положительной нумерации? Подводные камни дефрагментации.

Понял, что с отрицательной тоже жить можно.
Старый 25.11.2011, 13:07   #6  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 432 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от DreamCreator Посмотреть сообщение
Доброе утро!

Вчера на рабочей базе появились отрицательные RecId -620715238, хотя за день до этого RecId был в районе 1367137064.

Хотелось бы узнать - есть ли способы узнать на какие таблицы были сгенерированы RecId?

Также интересуют особенности работы с отрицательными RecId. Про кратность 256 прочитал.

Спасибо!
Ax 3.0 SP3
В третьей версии аксапты у нас неоднократно, самопроизвольно RecId перескакивали на несколько млн или уходили в "минус". Закономерности определить не удалось. При этом никаких "внешних" обращений к БД, минуя ядро Аксапты, не производилось.

"Возвращать" recId на "место" можно и нужно.

Так как с отрицательными recId будет масса глюков в российском функционале (ЗП кадры и так далее - неоднократно обсуждалось на форуме) Либо исправлять все эти модули, (и не только Российские кстати, но там ошибок больше всего)

Использовали такой джоб для перевода счетчика:

X++:
static void Job9(Args _args)
{
    SystemSequences SystemSequences;
    Connection con = new Connection();
    Statement stmt;
    ;


    con.ttsbegin();

    stmt = con.createStatement();
    stmt.executeUpdate('UPDATE SystemSequences SET nextVal=456400000 WHERE (id=-1) and (DATAAREAID=\''+ "dat" +'\')'); // впишите тут вашу компанию
    con.ttscommit();


    select SystemSequences
    where (SystemSequences.id == -1) && (SystemSequences.dataAreaId == 'dat');


    info(chi_str(SystemSequences.nextVal)); // возвращает текущее значение счетчика
}
Дефрагментацию делать не стоит, пока есть большие свободные диапазоны RecId

Нужно лишь найти диапазоны не используемых recId.
Собрать свободные диапазоны RecId можно джобом, который может собрать статистику используемых recId по наиболее активным и крупным таблицам. Могу привести пример если нужно будет...

Последний раз редактировалось someOne; 25.11.2011 в 14:13.
За это сообщение автора поблагодарили: Pustik (1), Logger (2), DreamCreator (3).
Старый 25.11.2011, 13:47   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
При импорте из файла часто соскакивают.
Были на форуме посты на эту тему, поищите.
Fed кажется писал.
Старый 25.11.2011, 13:48   #8  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
См. также
Миф об уникальности RecId?
Старый 25.11.2011, 13:58   #9  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Thumbs up
Цитата:
Сообщение от someOne Посмотреть сообщение
В третьей версии аксапты у нас неоднократно, самопроизвольно RecId перескакивали на несколько млн или уходили в "минус". Закономерности определить не удалось. При этом никаких "внешних" обращений к БД, минуя ядро Аксапты, не производилось.

"Возвращать" recId на "место" можно и нужно.

Так как с отрицательными recId будет масса глюков в российском функционале (ЗП кадры и так далее - неоднократно обсуждалось на форуме) Либо исправлять все эти модули, (и не только Российские кстати, но там ошибок больше всего)

Дефрагментацию делать не стоит, пока есть большие свободные диапазоны RecId

Нужно лишь найти диапазоны не используемых recId.
Собрать свободные диапазоны RecId можно джобом, который может собрать статистику используемых recId по наиболее активным и крупным таблицам. Могу привести пример если нужно будет...
Большое Спасибо!
Решили пока понаблюдать. В случае критичных глюков переключим RecId на продолжение положительного диапазона.

Поиск свободных диапазонов пока не нужен - есть примерное последнее RecId 1367133505 на котором остановилось, думаю к нему можно прибавить немного и продолжить. Но буду иметь в виду, Спасибо!
Старый 25.11.2011, 14:25   #10  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от Logger Посмотреть сообщение
При импорте из файла часто соскакивают.
Были на форуме посты на эту тему, поищите.
Fed кажется писал.
Спасибо! Нашел эту тему

RecId скакнула как раз во время импорта из xml-файла, но это самописный импорт - перебираются записи из файла, и аккуратно вставляются insert (не insert_recordset)
Старый 25.11.2011, 14:45   #11  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Спасибо! С утра эту ветку читаю
Интересная идея использования дыр!
Старый 26.11.2011, 17:15   #12  
Bega is offline
Bega
Участник
Аватар для Bega
 
382 / 444 (15) +++++++
Регистрация: 18.08.2005
Адрес: Москва
Цитата:
Сообщение от DreamCreator Посмотреть сообщение
Большое Спасибо!
Решили пока понаблюдать. В случае критичных глюков переключим RecId на продолжение положительного диапазона.

Поиск свободных диапазонов пока не нужен - есть примерное последнее RecId 1367133505 на котором остановилось, думаю к нему можно прибавить немного и продолжить. Но буду иметь в виду, Спасибо!
Помню, что у нас на 3.0 были проблемы с расчетом по средней при закрытии склада, в методе InventCostItemDim::updateModelAverage есть сортировка по RecId, с отрицательными начинает работать неверно.
За это сообщение автора поблагодарили: DreamCreator (2).
Старый 28.11.2011, 09:02   #13  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
:)
Цитата:
Сообщение от Bega Посмотреть сообщение
Помню, что у нас на 3.0 были проблемы с расчетом по средней при закрытии склада, в методе InventCostItemDim::updateModelAverage есть сортировка по RecId, с отрицательными начинает работать неверно.
Спасибо! Проверил код - сортировка закомментирована 4 года назад
X++:
//index hint RecIdTypeIdx
Старый 28.11.2011, 11:30   #14  
Bega is offline
Bega
Участник
Аватар для Bega
 
382 / 444 (15) +++++++
Регистрация: 18.08.2005
Адрес: Москва
Цитата:
Сообщение от DreamCreator Посмотреть сообщение
Спасибо! Проверил код - сортировка закомментирована 4 года назад
X++:
//index hint RecIdTypeIdx
Нет, это у вас хинт закомментирован, он на сортировку не влияет. Я нашел у себя вот такую модификацию:
X++:
...
while (mEnum.moveNext())
                {
                    receipt             = mEnum.currentValue();

                    inventTransKey      = inventCostItemDim::keyAdjust2String(receipt.inventTransId,receipt.inventTransIdReturn,receipt.voucher);
                    financialOpenQty    = mapInventTransIdQty.lookup(inventTransKey);

// dyol 17.08.2009 OK000754 -->
                    //sortReceiptKey      = InventCostItemDim::qtyRecId2String(mapInventTransIdQty.lookup(inventTransKey) / mapInventTransIdTotal.lookup(inventTransKey)*exp10(9), receipt.recId);
                    sortReceiptKey      = InventCostItemDim::qtyRecId2String_OK(mapInventTransIdQty.lookup(inventTransKey) / mapInventTransIdTotal.lookup(inventTransKey)*exp10(9),
                                                                                receipt.recId,
                                                                                receipt.DateFinancial);
// dyol 17.08.2009 OK000754 <--

                    mapSortedReceipt.insert(sortReceiptKey,receipt);
                    mapInventTransIdQty.insert(inventTransKey, financialOpenQty+receipt.financialOpenQty());
                }
...
Добавлен новый метод:
X++:
// dyol 17.08.2009 OK000754  -->
static str qtyRecId2String_OK(Real        _qty,
                              Recid       _recId,
                              TransDate   _transDate)
{
    str qtyStr;
    str recIdStr;
    str key;

    qtyStr = int2str(trunc(_qty));
    recIdStr = int2str(abs(_recId));
    if (_recId < 0)
        key = strrep('0',20-strlen(qtyStr))+qtyStr + date2str(_transDate, 321, 2, 0, 2, 0, 4) + '#-' + strrep('0',15-strlen(recIdStr))+recIdStr;
    else
        key = strrep('0',20-strlen(qtyStr))+qtyStr + date2str(_transDate, 321, 2, 0, 2, 0, 4) + '#0' + strrep('0',15-strlen(recIdStr))+recIdStr;
    return key;
}
// dyol 17.08.2009 OK000754  <--
То есть, дата включается явно в ключ перед RecId, чтобы сортировалось правильно.

Последний раз редактировалось Bega; 28.11.2011 в 11:33.
За это сообщение автора поблагодарили: DreamCreator (2).
Старый 28.11.2011, 14:18   #15  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от Bega Посмотреть сообщение
Нет, это у вас хинт закомментирован, он на сортировку не влияет. Я нашел у себя вот такую модификацию:

То есть, дата включается явно в ключ перед RecId, чтобы сортировалось правильно.
Большое Спасибо!
Старый 28.11.2011, 17:18   #16  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 432 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от Bega Посмотреть сообщение
Помню, что у нас на 3.0 были проблемы с расчетом по средней при закрытии склада, в методе InventCostItemDim::updateModelAverage есть сортировка по RecId, с отрицательными начинает работать неверно.
Это не единственная проблема с отрицательными RecId...

Как вам примеры такого кода, например в таблице RPayCounterTable
X++:
static boolean checkScan(RPaySequence paySequence)
{
    RPayCounterTable payCounterTable;
    ;

    if (paySequence)
        select firstonly firstfast payCounterTable
            index hint ScanningIdx
            where payCounterTable.scanning == paySequence;


return payCounterTable.recId;
}
В этом месте (return payCounterTable.recId) при отрицательных RecId для некоторых вариантов значений (кратных 16 кажется) результат будет не верный!

Для корректной работы придется все такие методы переписать на
X++:
    return payCounterTable.recId != 0;
Таких мест много в системе, и не только для Российского функционала...
Старый 28.11.2011, 17:36   #17  
DreamCreator is offline
DreamCreator
Moderator
Аватар для DreamCreator
Axapta Retail User
 
553 / 45 (3) +++
Регистрация: 04.11.2004
Адрес: Казань
Цитата:
Сообщение от someOne Посмотреть сообщение
Это не единственная проблема с отрицательными RecId...

Как вам примеры такого кода, например в таблице RPayCounterTable

В этом месте (return payCounterTable.recId) при отрицательных RecId для некоторых вариантов значений (кратных 16 кажется) результат будет не верный!

Для корректной работы придется все такие методы переписать на
X++:
    return payCounterTable.recId != 0;
Таких мест много в системе, и не только для Российского функционала...
Спасибо! Мы не используем зарплату, но буду иметь в виду. Проблему кратности 256 в выражениях if(table.recId) знаю - сам вроде так не писал, запущу поиск по АОТ на всякий случай.
Старый 29.11.2011, 10:20   #18  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от someOne Посмотреть сообщение
...

В этом месте (return payCounterTable.recId) при отрицательных RecId для некоторых вариантов значений (кратных 16 кажется) результат будет не верный!

Для корректной работы придется все такие методы переписать на
X++:
    return payCounterTable.recId != 0;
Таких мест много в системе, и не только для Российского функционала...
ага, это известная проблема. Про неё уже все что можно исписано. НО почему то везде упорно продолжаются использовать неявное преобразование.... повсеместно встречаются конструкции типа:
X++:
if (myTable.recId)
или
X++:
return myTable.recId;
интересно почему?

P.S. конечно после перевода RecId на 64 бита отрицательный RecId маловероятен, но все таки лучше делать явное преобразование соответствующего типа!
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 29.11.2011, 10:49   #19  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от lev Посмотреть сообщение
P.S. конечно после перевода RecId на 64 бита отрицательный RecId маловероятен, но все таки лучше делать явное преобразование соответствующего типа!
После перевода RecId на 64 бита, отрицательный RecId чуть менее вероятен чем в 32-битном варианте. Обсуждалось вот здесь
За это сообщение автора поблагодарили: lev (2).
Старый 29.11.2011, 10:59   #20  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от fed Посмотреть сообщение
После перевода RecId на 64 бита, отрицательный RecId чуть менее вероятен чем в 32-битном варианте. Обсуждалось вот здесь
Ага импорт я упустил из вида, спасибо!
Тогда надо запрещать конструкции кода приведенные мной и someOne в прошлых сообщениях на уровне компниляции!
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Миф об уникальности RecId? Alenka DAX: Программирование 51 22.08.2013 13:12
Формирование RecId при вставке в таблицу AX из SQL Server Hyper DAX: Программирование 20 28.06.2011 17:30
axforum blogs: Переделываем RecId в таблицах Blog bot DAX Blogs 0 06.05.2011 19:11
if (record) vs if (record.RecId) kashperuk DAX: Программирование 18 27.11.2008 18:53
поля, содержащие RecId somebody DAX: Программирование 15 16.05.2008 17:50

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

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

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