|
|
#8 |
|
Участник
|
Вот пример джоба :
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: uplicateKeyExceptionкоторые в свою очередь не откатывают транзакцию. Поэтому чтобы избегать в модификациях подобных ошибок, нельзя ставить обработку 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, баг, исключения |
|
|
|