13.06.2013, 12:11 | #1 |
Участник
|
axforum blogs: ExecuteMultiple может приводить к взаимным блокировкам в базе
Источник: http://axforum.info/forums/blog.php?b=407
============== Начиная с UR12 система поддерживает новый разрекламированный запрос ExecuteMultipleRequest позволяющий пачками отправлять запросы к системе без необходимости обрабатывать каждое сообщение по отдельности. Эта возможность показалась мне удобной, поэтому я переписал под новую функцию весь свой код, где записи создавались в цикле. Изменение хорошо прошло тестирование на небольшом примере, но в реальной жизни почему-то возникли проблемы. Сценарий: действия пользователя в системе приводят к срабатыванию асинхронного плагина 1 (запуск массовой операции). Плагин производит вычитку данных и использует ExecuteMultipleRequest для создания произвольного количества записей (операций). За выполнение операций отвечает синхронный плагин 2. Основной момент операций заключается в том, что они должны выполняться последовательно, так как в них происходит работа с данными, поэтому работа с базой в плагине 2 реализована с использованием блокировки: X++: lock (SyncLock){ service.Create(operation);} Запуск массовой операции приводящей к созданию дочерних записей в количестве больше двух приводит к ошибке SQL Timeout. Гуглинг привел меня к скрипту, который, предположительно позволяет определить причину блокировки: http://blog.sqlauthority.com/2010/10...irty-solution/ К сожалению, я не большой эксперт по SQL поэтому никак не могу его прокомментировать. Первые попытки отладки показали мне достаточно странные результаты: скрипт выдавал, что к блокировке приводит безобидная операция чтения, которая, к тому же, еще и выполняется в родительском плагине до запуска дочерних. Переписав блокирующий запрос с использованием QueryExpression с ключом NoLock (вместо использованного ранее QueryByAttribute) я получил чуть более правдоподобный блокирующий запрос: X++: select "sdkmessageprocessingstep0".Stage as "stage","sdkmessageprocessingstep0".SdkMessageProcessingStepId as "sdkmessageprocessingstepid" from SdkMessageProcessingStep as "sdkmessageprocessingstep0" where (("sdkmessageprocessingstep0".StateCode = @StateCode0 and ("sdkmessageprocessingstep0".Stage in (@Stage0 , @Stage1 , @Stage2 , @Stage3 , @Stage4 , @Stage5 , @Stage6)) and "sdkmessageprocessingstep0".SdkMessageId = @SdkMessageId0 and "sdkmessageprocessingstep0".InvocationSource = @InvocationSource0 and (("sdkmessageprocessingstep0".SdkMessageFilterId is null or "sdkmessageprocessingstep0".SdkMessageFilterId = @SdkMessageFilterId0)) and (("sdkmessageprocessingstep0".SupportedDeployment = @SupportedDeployment0 or "sdkmessageprocessingstep0".SupportedDeployment = @SupportedDeployment1)))) order by "sdkmessageprocessingstep0".Rank asc , "sdkmessageprocessingstep0".SdkMessageFilterId asc Я не готов с уверенностью сказать, что проблема заключается в том, что плагины не могут определиться в какой последовательности запускаться, однако переписав код под создание записей в цикле мне удалось устранить проблему. Если у кого-то есть дополнительные сведения, об этой проблеме, пожалуйста отпишитесь в комментариях. Источник: http://axforum.info/forums/blog.php?b=407
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
|