|
02.12.2014, 12:27 | #1 |
Участник
|
Это фича, или я что-то не так делаю?
AX2012 R2
Обновляю цену на строке закупки X++: purchLine.PurchPrice = MyPrice; purchLine.LineAmount = purchLine.calcLineAmount(); purchLine.update() При отладке наткнулась на сообщение: "Cannot create a record in Relationship between the purchase order line and the inventory transactions originator (InventTransOriginPurchLine). Inventory transactions originator: SomeInvTransNum123, SomeInvTransNum123. The record already exists" Которое потом "исчезает". Далее вышла на волшебный метод InventTransOriginPurchLine-> writeOriginOwnerRelationship() Где написано следующее : X++: catch (Exception::DuplicateKeyException) { if (xSession::lastDuplicateKeyViolatingTable() == inventTransOriginPurchLine) { update_recordset inventTransOriginPurchLine setting InventTransOrigin = _inventTransOriginId where inventTransOriginPurchLine.PurchLineInventTransId == _purchLineInventTransId && inventTransOriginPurchLine.PurchLineDataAreaId == _purchLineDataAreaId && inventTransOriginPurchLine.InventTransOrigin != _inventTransOriginId; } else { throw Exception::DuplicateKeyException; } infolog.clear(logCount); } Вот вопрос : обновление цены на purchLine неправильно реализовано, или все так и должно быть, и надо просто смириться? Последний раз редактировалось IKA; 02.12.2014 в 12:34. |
|
02.12.2014, 13:01 | #2 |
Участник
|
Смиритесь)
Exception:: DuplicateKeyException не прерывает выполнение транзакции. Таким способом проверяют, что запись уже существует (отдельный select для этого не стали делать)
__________________
Axapta v.3.0 sp5 kr2 |
|
02.12.2014, 13:09 | #3 |
Участник
|
при желании можно переписать в классически вид, вреда особо не будет
|
|
02.12.2014, 19:59 | #4 |
Участник
|
Проблема в том. что этот код периодически затирает весь инфолог, а не только те строки, что записались при DuplicateKeyException . Воспроизвести не всегда получается. Если я отлаживаю код в дебаггере, то все ок. Если без дебаггера запускаю, то периодически исчезают строки из инфолога.
Я грешу на метод X++: Counter logCount = infologLine(); Цитата:
This method has similar functionality to the <c>xInfo.line</c> method, but it improves performance
/// and lowers network load when you are executing server-side code.When the <c>xInfo.line</c> method /// is run on the server, it makes a call to the client to retrieve the number of lines in the Infolog /// buffer. The <c>xGlobal::infologLine</c> method retrieves the server-side Infolog buffer line count. /// This eliminates the requirement to call to the client. When the <c>xGlobal::infologLine</c> method /// is called on the client, it returns the count directly from the Infolog buffer on the client.This /// method is especially useful when you write server-side code that processes exceptions.The number of /// lines in the Infolog is generally stored before entering a <c>try</c> / <c>catch</c> block.If an /// exception occurs, the number of lines that were previously stored is used to determine which /// messages were logged during the code in the <c>try</c> block. If no exceptions occur, the stored /// Infolog buffer line count is often unused. If you use the <c>xGlobal::infologLine</c> method /// instead of the <c>xInfo.line</c> method to retrieve the Infolog lines, a round-trip to the client /// is prevented. /// </remarks> X++: xInfo.line Последний раз редактировалось IKA; 02.12.2014 в 20:25. |
|
02.12.2014, 20:29 | #5 |
Участник
|
Да, писали этот код феерические пидарасы.
Которым каждый раз хочется оторвать то, что болтается. там еще есть попытка "управлять" инфологом, подсчитывать количество "ненужных" сообщений и стирать только "ненужные". При этом разработчик похоже не знал о префиксах и иерархии в инфологе. Цитата:
Что нужно сделать обязательно: 1. при помощи перекрестных ссылок найти все попытки очистить инфолог, закомментировать такие попытки 2. при помощи перекрестных ссылок найти все попытки удалять строки в инфологе поотдельности, провести более тщательный анализ и закомментировать такие попытки и обвязку вокруг них (подсчет строк, запоминание первой "ненужной" строки, удаление строк и инфолога начиная с первой "ненужной") дело в том, что таких мест несколько. и значимые сообщения пропадают не в одном месте. |
|
|
За это сообщение автора поблагодарили: f18 (2). |
03.12.2014, 12:51 | #6 |
Британский учённый
|
Я бы просто добавил проверку на дубликаты перед try() а catch бы так и оставил.
Еще как идея, для isDeveloper() можно в clear() не очищать диалог, а добавлять сообщение, что была попытка очистить диалог. Как минимум облегчит отладку и поиск таких косяков. Это если нет желания перелопачивать весь код.
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. Последний раз редактировалось Link; 03.12.2014 в 12:55. |
|
03.12.2014, 16:40 | #7 |
Участник
|
|
|
03.12.2014, 17:23 | #8 |
Британский учённый
|
Это да, я предложил с позиции отладки. Отключить для всех можно в тестовой среде, а то не ясно где начнут вылазить ранее затираемые сообщения и в каких количествах.
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. |
|
05.12.2014, 19:55 | #9 |
Участник
|
вообщем, так и есть ((
В коде решила писать в таблицу(пишу не в infolog, а таблицу, чтобы лишний раз его не "дергать с сервера" и т.о не обновлять его) значения, возвращаемые обеими функциями X++: infologLine(); infolog.line(); Может, из-за неправильной работы самого infolog.clear(logCount) с серв и клиентским объектом - будет время. еще поиграю ... Только вот странно. что в интернете нет ссылок на этот баг.... Последний раз редактировалось IKA; 05.12.2014 в 20:10. |
|
05.12.2014, 20:14 | #10 |
Участник
|
Clear не виноват.
Без него то же самое происходит. Причем, интересно, что на следующей итерации "после сбойной" значения уже корректные. То есть, допустим, что-то пишет в инфолог 4 записи, то имеем, например, вот такие результаты: It1: infologLine()=1, infolog.line = 1, It2: infologLine()=2, infolog.line = 2, It2: infologLine()=0, infolog.line = 3, It2: infologLine()=4, infolog.line = 4 Последний раз редактировалось IKA; 05.12.2014 в 20:17. |
|