25.11.2011, 09:40 | #1 |
Moderator
|
Кто использовал RecId
Доброе утро!
Вчера на рабочей базе появились отрицательные RecId -620715238, хотя за день до этого RecId был в районе 1367137064. Хотелось бы узнать - есть ли способы узнать на какие таблицы были сгенерированы RecId? Также интересуют особенности работы с отрицательными RecId. Про кратность 256 прочитал. Спасибо! Ax 3.0 SP3 |
|
25.11.2011, 09:46 | #2 |
Участник
|
У нас уже 2 года отрицательные и ничего!
В чем может быть проблема? Ну только если сортировку делать по RecID и попадутся вместе отрицательные и положительные - но, я думаю, в здравом уме никто так не делает. Более причин для беспокойства не вижу.
__________________
Axapta 3.0 sp - хз какой, kr2 |
|
25.11.2011, 09:58 | #3 |
Moderator
|
Цитата:
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 |
Модератор
|
Импорт делал?
Георгий |
|
25.11.2011, 11:19 | #5 |
Moderator
|
Нет - не ровном месте скакнуло.
Подозрения 2: 1. Какая-то операция в Аксапте мгновенно отъела миллиард RecId за 13 секунд. 2. Возникли блокировки SYSTEMSEQUENCES и счетчик каким-то образом сбился на отрицательные значения. Сейчас вопросы: 1. Что могло вызвать такой скачек? 2. Поможет ли дефрагментация вернуться к прежней положительной нумерации? Подводные камни дефрагментации. Понял, что с отрицательной тоже жить можно. |
|
25.11.2011, 13:07 | #6 |
Участник
|
Цитата:
Сообщение от DreamCreator
Доброе утро!
Вчера на рабочей базе появились отрицательные RecId -620715238, хотя за день до этого RecId был в районе 1367137064. Хотелось бы узнать - есть ли способы узнать на какие таблицы были сгенерированы RecId? Также интересуют особенности работы с отрицательными RecId. Про кратность 256 прочитал. Спасибо! Ax 3.0 SP3 "Возвращать" 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 по наиболее активным и крупным таблицам. Могу привести пример если нужно будет... Последний раз редактировалось someOne; 25.11.2011 в 14:13. |
|
|
За это сообщение автора поблагодарили: Pustik (1), Logger (2), DreamCreator (3). |
25.11.2011, 13:47 | #7 |
Участник
|
При импорте из файла часто соскакивают.
Были на форуме посты на эту тему, поищите. Fed кажется писал. |
|
25.11.2011, 13:48 | #8 |
Участник
|
См. также
Миф об уникальности RecId? |
|
25.11.2011, 13:58 | #9 |
Moderator
|
Цитата:
Сообщение от someOne
В третьей версии аксапты у нас неоднократно, самопроизвольно RecId перескакивали на несколько млн или уходили в "минус". Закономерности определить не удалось. При этом никаких "внешних" обращений к БД, минуя ядро Аксапты, не производилось.
"Возвращать" recId на "место" можно и нужно. Так как с отрицательными recId будет масса глюков в российском функционале (ЗП кадры и так далее - неоднократно обсуждалось на форуме) Либо исправлять все эти модули, (и не только Российские кстати, но там ошибок больше всего) Дефрагментацию делать не стоит, пока есть большие свободные диапазоны RecId Нужно лишь найти диапазоны не используемых recId. Собрать свободные диапазоны RecId можно джобом, который может собрать статистику используемых recId по наиболее активным и крупным таблицам. Могу привести пример если нужно будет... Решили пока понаблюдать. В случае критичных глюков переключим RecId на продолжение положительного диапазона. Поиск свободных диапазонов пока не нужен - есть примерное последнее RecId 1367133505 на котором остановилось, думаю к нему можно прибавить немного и продолжить. Но буду иметь в виду, Спасибо! |
|
25.11.2011, 14:25 | #10 |
Moderator
|
Цитата:
RecId скакнула как раз во время импорта из xml-файла, но это самописный импорт - перебираются записи из файла, и аккуратно вставляются insert (не insert_recordset) |
|
25.11.2011, 14:45 | #11 |
Moderator
|
Цитата:
Сообщение от S.Kuskov
См. также
Миф об уникальности RecId? Интересная идея использования дыр! |
|
26.11.2011, 17:15 | #12 |
Участник
|
Цитата:
Сообщение от DreamCreator
Большое Спасибо!
Решили пока понаблюдать. В случае критичных глюков переключим RecId на продолжение положительного диапазона. Поиск свободных диапазонов пока не нужен - есть примерное последнее RecId 1367133505 на котором остановилось, думаю к нему можно прибавить немного и продолжить. Но буду иметь в виду, Спасибо! |
|
|
За это сообщение автора поблагодарили: DreamCreator (2). |
28.11.2011, 09:02 | #13 |
Moderator
|
Цитата:
X++: //index hint RecIdTypeIdx |
|
28.11.2011, 11:30 | #14 |
Участник
|
Цитата:
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 <-- Последний раз редактировалось Bega; 28.11.2011 в 11:33. |
|
|
За это сообщение автора поблагодарили: DreamCreator (2). |
28.11.2011, 14:18 | #15 |
Moderator
|
|
|
28.11.2011, 17:18 | #16 |
Участник
|
Цитата:
Как вам примеры такого кода, например в таблице 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; } Для корректной работы придется все такие методы переписать на X++: return payCounterTable.recId != 0; |
|
28.11.2011, 17:36 | #17 |
Moderator
|
Цитата:
Сообщение от someOne
Это не единственная проблема с отрицательными RecId...
Как вам примеры такого кода, например в таблице RPayCounterTable В этом месте (return payCounterTable.recId) при отрицательных RecId для некоторых вариантов значений (кратных 16 кажется) результат будет не верный! Для корректной работы придется все такие методы переписать на X++: return payCounterTable.recId != 0; |
|
29.11.2011, 10:20 | #18 |
Ищущий знания...
|
Цитата:
Сообщение от 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 |
Moderator
|
Цитата:
|
|
|
За это сообщение автора поблагодарили: lev (2). |
29.11.2011, 10:59 | #20 |
Ищущий знания...
|
Цитата:
Сообщение от fed
После перевода RecId на 64 бита, отрицательный RecId чуть менее вероятен чем в 32-битном варианте. Обсуждалось вот здесь
Тогда надо запрещать конструкции кода приведенные мной и someOne в прошлых сообщениях на уровне компниляции!
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|