| 
			
			 | 
		#1 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			
			PurchLine update conflict ??
			 
			
			Мне нужно присвоить новые значения полю PurchLine.PurchReceivedNow , код приблизительно такой:  
		
		
		
		
		
		
		
		
			X++: ttsBegin; while select forupdate purchLine order by Confirmeddlv where purchLine.PurchId == purchId && purchLine.ItemId == itemId && purchLine.PurchStatus == PurchStatus::Backorder && (!purchLine.IsDeleted) exists join InventDim where lalala { // purchLine.reread(); if (receivedQty >= purchLine.RemainPurchPhysical) { purchLine.PurchReceivedNow = purchLine.RemainPurchPhysical; receivedQty -= purchLine.RemainPurchPhysical; } else { purchLine.PurchReceivedNow = receivedQty; receivedQty = 0; } purchLine.setInventReceivedNow(); purchLine.Tax1099Amount = 0; purchLine.Tax1099StateAmount = 0; if (purchLine.validateWrite()) { purchLine.update(); } else { throw error('my error'); } } Ax2012 R2 Последний раз редактировалось IKA; 06.03.2014 в 17:35.  | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Сенбернар 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Уточните, пожалуйста, что там подразумевается под lalala. И зачем - exists join ? 
		
		
		
		
		
		
			---- Предварительный диагноз : - по exists join вы одну и ту же PurchLine находите не один, а больше раз. - поскольку весь цикл - внутри транзакции - при попытке повторно изменить запись (без reread()) - происходит тот самый update conflict Вот как-то так 
				__________________ 
		
		
		
		
		
			Best Regards, Roman Последний раз редактировалось RVS; 06.03.2014 в 18:55.  | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			1) каким образом exists может приводить к дупликатам??????? 
		
		
		
		
		
		
		
	2) дело точно не в inventDim , тк в дебаггере видно. что разные записи purchLine выбираются  | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 Сенбернар 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Условие "lalala" расшифруйте - тогда объясню, каким. Если может, конечно )) 
		
		
		
		
		
		
			Пока не вижу условия - могу только предполагать. Потоому и написал - "предварительный" диагноз ) 
				__________________ 
		
		
		
		
	Best Regards, Roman  | 
| 
	
 | 
| 
			
			 | 
		#5 | 
| 
			
			 Moderator 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Попробуйте включить трассировку SQL и посмотреть (по сохраненному стеку вызовов) из какого куска кода реально идет обновление purchLine. Ваш purchLine.update() втихаря порождает вызов inventUpd_estimated, в котором много чего интересного происходит. Есть шансы что из за кастомизаций или из за какого-нить неаккуратно отключенного регионального функционала, этот код находит еще одну копию того же самого purchLine, меняет ее и обновляет. Когда после этого доходит дело до обновления в самом purchLine.update(), система начинает ругаться, потому что номер версии записи в переданном буфере и номер версии записи в БД - не совпадают.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: MikeR (10), S.Kuskov (2). | |
| 
			
			 | 
		#6 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Нет тогда бы purchLine.reread() не помог бы избежать конфликта, т.к. стоит в самом начале итерации. Обновляется другая запись, не та (или не только та) запись которая выбрана на текущей итерации, но тоже присутствующая в выборке.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: IKA (1). | |
| 
			
			 | 
		#7 | 
| 
			
			 Сенбернар 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А почему бы не сделать "естественным образом"? Вот так, например : 
		
		
		
		
		
		
			X++: ttsBegin; while select forupdate purchLine order by Confirmeddlv where purchLine.PurchId == purchId && purchLine.ItemId == itemId && purchLine.PurchStatus == PurchStatus::Backorder && ! purchLine.IsDeleted join inventDim where inventDim.InventDimId == purchLine.InventDimId && lalala { // Что-то делаем с purchLine purchLine.update(); } IKA, напишите, как решилось, пожалуйста. Случай странный, ИМХО ) 
				__________________ 
		
		
		
		
	Best Regards, Roman  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А у вас случаем не активен чек активировать управление изменениями в параметрах модуля закупок и источников ? 
		
		
		
		
		
		
			Просто в стандарте в методе update строки покупки вшит код, который в некоторых случая при обновлении данных по одной строке запускает массовую обработку по всем строкам текущего заказа см. PurchLineType\updatePurchTable (строка с VersioningPurchaseOrder\change, там кстати вызов идет через doUpdate других строк). Цитата: 
	
		
			А почему бы не сделать "естественным образом"? 
		
	 
				__________________ 
		
		
		
		
	Sergey Nefedov  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: RVS (1), IKA (1). | |
| 
			
			 | 
		#9 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Если кому интересно, я накопала в чем проблема, вот ток как лечить - ума не приложу, тк мне кажется, это баг 
		
		
		
		
		
		
		
		
			Все дело в коде класса VersioningPurchaseOrder метод archivePurchLine, в самом конце вызывыается такое дело : X++: purchLine.skipDataMethods(true); purchLine.skipDatabaseLog(true); update_recordset purchLine setting IsModified = NoYes::No where purchLine.PurchId == purchTable.PurchId && purchLine.IsModified && purchLine.InventTransId != skipInventTransId; Дело в том,что мне кажется, это куски того, что должно вызываться при галке, упомянутой SRF , но 1) у нас она не стоит 2) в коде нет никаких проверок на какие-либо парметры и настройки (ну или я не вижу). Стек вызовов у меня такой X++: [s] \Classes\VersioningPurchaseOrder\archivePurchLine 99 [s] \Classes\VersioningPurchaseOrder\archiveCurrentVersion 28 [s] \Classes\VersioningDocument\change 40 [s] \Classes\VersioningPurchaseOrder\change 26 [s] \Classes\PurchLineType\updatePurchTable 11 [s] \Classes\PurchLineType\update 79 [s] \Classes\PurchLineType_Purch\update 38 [s] \Data Dictionary\Tables\PurchLine\Methods\update 17 Вопрос вечный : Кто виноват и что теперь делать??? Последний раз редактировалось IKA; 07.03.2014 в 14:53.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Мартынов Дмитрий (1). | |
| 
			
			 | 
		#10 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А чем не устраивает исходное решение - дергать внутри цикла purchLine.reread()?
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			На всяк случай, значения параметров:  
		
		
		
		
		
		
		
	purchLineType.update(dropInvent, false, updateOrderLineOfDeliverySchedule) - здесь dropInvent = false, updateOrderLineOfDeliverySchedule = true В purchLineType_Purch -> update вызов super(_dropInvent, _forceInterCompanyMirror, _updateOrderLineOfDeliverySchedule); , тут _dropInvent = false _forceInterCompanyMirror = false _updateOrderLineOfDeliverySchedule = true Дальше все вызывается без параметров  | 
| 
	
 | 
| 
			
			 | 
		#12 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Да, этот вызов я и имел ввиду. Он также может вызываться если у закупки статус Подтверждено, у вас в покупке этот статус, если да, попробуйте на какой нибудь у которой этот статус другой. Т.е. массово обновлять строки в покупке лучше до того момента пока эта покупка имеет статус до подтверждено. В стандарте есть ряд ключевых полей при изменении которых этот статус сбрасывается всегда, и потом требуется повторное подтверждение.
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
		
			Sergey Nefedov Последний раз редактировалось SRF; 07.03.2014 в 15:04.  | 
| 
	
 | 
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			2gl00mie: Смысл писать в while select forupdate, если записи могут быть обновлены втихоря другой транзакцией?
		 
		
		
		
		
		
		
		
		
			Последний раз редактировалось IKA; 07.03.2014 в 14:56.  | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Во-первых, в 2012-й для PurchLine по умолчанию включена OCC, так что forupdate и так не накладывает по умолчанию никаких блокировок в БД, во-вторых, с точки зрения СУБД это не другая транзакция, а ваша же собственная, в которой вы лопатите строки закупки. Просто в данной ситуации, образно говоря, правая рука не знает, что делает левая, но зато есть очень простое решение - перечитать запись перед обработкой, так почему бы этим решением не воспользоваться?  
		
		
		
		
		
		
		
	 
		 | 
| 
	
 | 
| 
			
			 | 
		#15 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Я бы всё-таки предпочел выяснить, в какой момент запись обновляется извне, чтобы убедиться, что без reread никак, и спать спокойно. Хотя это может занять какое-то время.  
		
		
		
		
		
		
		
	Однажды с таким столкнулся, и исправил косяк в том, другом методе, так что reread не понадобился.  | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Выше приведен стек вызовов, показывающий, в какой момент запись обновляется "извне"  
		
		
		
		
		
		
		
	 
		 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Stitch_MS (1). | |
| 
			
			 | 
		#17 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Подниму тему. 
		
		
		
		
		
		
		
	проблема в том, что не работает purchLine.skipDataMethods(true); X++: purchLine.skipDataMethods(true); purchLine.skipDatabaseLog(true); update_recordset purchLine setting IsModified = NoYes::No where purchLine.PurchId == purchTable.PurchId && purchLine.IsModified && purchLine.InventTransId != skipInventTransId; а вот в связи с чем он может не работать?  | 
| 
	
 | 
| 
			
			 | 
		#18 | 
| 
			
			 MCITP 
		
			
	 | 
	
	
	
		
		
			
			 Цитата: 
	
		
			Сообщение от under_construction
			 
 
			Подниму тему. 
		
	проблема в том, что не работает purchLine.skipDataMethods(true); X++: purchLine.skipDataMethods(true); purchLine.skipDatabaseLog(true); update_recordset purchLine setting IsModified = NoYes::No where purchLine.PurchId == purchTable.PurchId && purchLine.IsModified && purchLine.InventTransId != skipInventTransId; а вот в связи с чем он может не работать? Если речь про 2012, то AOSAuthorization Property на таблице у вас случайно не настроен? Тогда ещё .skipAosValidation() нужен будет 
				__________________ 
		
		
		
		
	Zhirenkov Vitaly  | 
| 
	
 | 
| 
			
			 | 
		#19 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Еще skipEvents() стоит попробовать - вдруг кто уведомления себе настроил.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: MikeR (5). | |
| 
			
			 | 
		#20 | 
| 
			
			 Участник 
		
			
	 | 
	
	|
| 
	
 | 
| Теги | 
| ax2012, ax2012r2 | 
| 
	
	 | 
	
		
		
  |