|
25.09.2009, 11:41 | #1 |
Участник
|
Разноски, блокировки и NumberSeq
Господа, доброго дня!
Аксапта тройка. Симптомы такие: для нескольких заказов при попытке разносок вешается намертво система, создаются два доступа к таблице NumberSequenceTable, один блочит другого. Происходит это в классе NumberSeqCleanUp в методе cleanUpSequence в этом запросе X++: select forupdate firstonly numberSequenceTableUpd index hint SeriesIdx where numberSequenceTableUpd.numberSequence == _numberSequenceTable.numberSequence; Происходит впервые, раньше не было такого как говорят, что согласуется со старыми топиками (работаю второй день на месте, впервые вижу проблемы с проводками такого класса). Помимо этого ещё появился глюк. При создании отгрузочной накладно процесс проходит, ничего не виснет, однако в проводках и в соответствующей таблице пустота. Ниже весь код, по-моему он оригинальный X++: public void cleanUpSequence(UserConnection userConnection, NumberSequenceTable _numberSequenceTable, boolean hookCleanUp = false ) { NumberSequenceList numberSequenceList; NumberSequenceTable numberSequenceTableUpd; boolean doCleanUpDead = FALSE; if (_numberSequenceTable && _numberSequenceTable.continuous) { userConnection.ttsbegin(); numberSequenceTableUpd.setConnection(userConnection); select forupdate firstonly numberSequenceTableUpd index hint SeriesIdx where numberSequenceTableUpd.numberSequence == _numberSequenceTable.numberSequence; if (numberSequenceTableUpd && (!hookCleanUp || numberSequenceTableUpd.mustRunCompleteCleanUp())) numberSequenceTableUpd.updateCompleteClean(); while select transId from numberSequenceList group by transId where numberSequenceList.numberSequence == _numberSequenceTable.numberSequence { if (!numberSequenceList.transId) doCleanUpDead = TRUE; this.cleanUpTrans(userConnection,numberSequenceList.transId); } if (doCleanUpDead) this.cleanupDeadProc(userConnection,_numberSequenceTable.numberSequence); userConnection.ttscommit(); } } Последний раз редактировалось Helm; 25.09.2009 в 11:53. |
|
25.09.2009, 12:09 | #2 |
Участник
|
А в чем вопрос ?
Хотите поймать глючное место ? Включите логирование долгих запросов. Дождитесь такого зависания, подождите минутку для верности, грохните одну из сессий на уровне SQL. Для второй сессии в логе длинных запросов увидите стек вызовов и прочие удобства для анализа ситуации. После нескольких таких упражнений, поймаете блокирующие и блокируемые места в коде. А дальше уже смотреть по обстоятельствам. |
|
25.09.2009, 12:18 | #3 |
Участник
|
Место-то я нашёл. Вопросы классические отечественные: что делать и кто виноват
Проблема как бы разбиралась, но не до конца... причём в одном топике всё закончилось на посте с аналогичной ситуацией. |
|
25.09.2009, 12:23 | #4 |
Участник
|
Цитата:
Блокировка NumberSequence к исправлениям в коде, пояснен принцип исправлений. Я думаю у вас нечто схожее. Т.е. основным соединением, в котором идут транзакции, выбираются forupdate записи из numberSequenceTable и прочих таблиц. А нужно использовать вновь открываемое соединение к базе, тогда эта таблица надолго блокироваться не будет и не будет блокировок и тупиковых ситуаций. |
|
25.09.2009, 13:24 | #5 |
Участник
|
Я извиняюсь за нупский вопрос, но как алгоритмически это сделать? Я просто раньше не сталкивался толком с UserConnect, да и полугодовой перерыв в работе даёт знать, к сожалению.
Вcё происходит в классе NumberSeqCleanUp В методе ран создаёт(только создаются) user connection, далее в нём просто вызывается X++: this.cleanUpSequence(userConnection,numberSequenceTableClean); X++: userConnection.ttsbegin(); numberSequenceTableUpd.setConnection(userConnection); select forupdate firstonly numberSequenceTableUpd index hint SeriesIdx where numberSequenceTableUpd.numberSequence == _numberSequenceTable.numberSequence; В примере с Release всё понятно, там были просто ttsbegin-commit и добавлялся connection внутрь их. А здесь как-то неясно мне, подскажите, пожалуйста! |
|
25.09.2009, 13:58 | #6 |
Участник
|
Ещё выяснилась подробность, что оказывается это не в первый раз, а уже бывало когда-то. И тогда лечилось брутфорсом в виде 20-30-кратного создания заказа, пока не удавалось провести разноску. Что только подтверждает данный баг... но конечно так лечить каждый раз не айс
|
|
25.09.2009, 12:19 | #7 |
Участник
|
Проблема может быть не только в методе release()
Могут быть и другие места. В фактурах например было место аналогичное. |
|
25.09.2009, 14:38 | #8 |
----------------
|
то что у вас вешается cleanUpSequence не причина, а следствие.
Надо найти место где данная номерная серия изменяется и не отпускается (не происходит commit транзакции) Возможно, в целях какой-то оптимизации у вас там в начале цикла ручками выделяется кусок серии. |
|
|
За это сообщение автора поблагодарили: Logger (1), Helm (1). |
28.09.2009, 12:49 | #9 |
Участник
|
Спасибо большое! Помогло
|
|
28.09.2009, 14:33 | #10 |
Участник
|
|
|
28.09.2009, 16:05 | #11 |
Участник
|
Я сам не понял, вылечилось шаманством в итоге.
Ошибка вылетала в результате попытки вставить уже имеющую строку в numberSequenceList, поиск по этой таблице глюкал почему-то. Вместо использования метода из NumberSeq зачем-то брался метод-наследник из NumberSeq_fast, который не должен был вообще ни с какого бока-припёка быть, и он возвращал пустую строку. Я просто закомментил строку с этим Insert'-ом, прогнал, сделал нужные фактуры. После чего убрал комментарий, решил ещё прогнать и всё вылечилось, заработало, т.к. стало использовать нужный метод. |
|
28.09.2009, 16:25 | #12 |
Участник
|
Цитата:
Сообщение от Helm
Я сам не понял, вылечилось шаманством в итоге.
Ошибка вылетала в результате попытки вставить уже имеющую строку в numberSequenceList, поиск по этой таблице глюкал почему-то. Вместо использования метода из NumberSeq зачем-то брался метод-наследник из NumberSeq_fast, который не должен был вообще ни с какого бока-припёка быть, и он возвращал пустую строку. Я просто закомментил строку с этим Insert'-ом, прогнал, сделал нужные фактуры. После чего убрал комментарий, решил ещё прогнать и всё вылечилось, заработало, т.к. стало использовать нужный метод. Можно еще индексы пересоздать. |
|
Теги |
блокировка, разноска, number sequence |
|
|