|
![]() |
#1 |
Участник
|
Вот пример джоба :
X++: // GRD_R4453_InventSumInventTrans_pkoz, Разъехались остатки в InventSum и проводки в InventTrans., pkoz, 04.11.2011 static void Job791_15(Args _args) { #define.recIdTrans(5637151827) InventTrans InventTrans; InventSum InventSum; ; try { ttsBegin; try { InventTrans = InventTrans::findRecId(#recIdTrans, true); InventTrans.Qty += 1.0; InventTrans.Update(); breakpoint; } catch { info("поймали внутрений catch"); } ttsCommit; } catch { info("поймали внешний catch"); } info(strFMT("InventTrans.RowCount() = %1, InventTrans.Qty = %2, InventSum : %3 ", InventTrans.RowCount(), InventTrans.Qty, con2str(Global::buf2Con(InventSum::find(InventTrans.ItemId, InventTrans.inventDimId)), "; ") )); } 1. Проставляем в джобе recID существующей проводки InventTrans 2. Открываем 2 клиента аксапты. 3. Запускаем джоб на 1-м клиенте, ждем когда он выпадет в отладчик на точке останова. 4. Запускаем тот же джоб на 2-м клиенте. Он повиснет. 5. Жмем F5 в отладчике на 1-м клиенте. В итоге после выполнения джоба на обоих клиентах, получаем что InventTrans.Qty увеличилось на 1, а соответствующая колонка в InventSum увеличилась на 2. Причина такого поведения, в том что мы просто поставили обработку catch в которую попадают исключения Exception::UpdateConflict и Exception: ![]() которые в свою очередь не откатывают транзакцию. Поэтому чтобы избегать в модификациях подобных ошибок, нельзя ставить обработку catch без указания вида исключения. Ну или по крайней мере перед ней всегда делать обработку вышеупомянутых типов исключений. Для удобства, я завел макрос Catch_DangerousException, который можно везде вставлять в блок обработки. Текст макроса X++: catch (Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= 5) { throw Exception::UpdateConflictNotRecovered; } else { retry; } } else { throw Exception::UpdateConflict; } } catch (Exception::DuplicateKeyException) { // info(strfmt("@SYS123267", )); if (appl.ttsLevel() != 0) { throw Exception::DuplicateKeyExceptionNotRecovered; } } X++: ... ttsBegin; try { // здесь расположен код обновляющий InventTrans - например комплектация или резервирование } catch(Exception::Error) { // обработка } #catch_DangerousException catch { // сюда попадает обработка конфликта обновления записи // ничего не делаем } ttsCommit; ... |
|
|
За это сообщение автора поблагодарили: Vadik (25), Ruff (10), kashperuk (20). |
Теги |
exception, inventsum, inventtrans, occ, try/catch, баг, исключения |
|
|