AXForum  
Вернуться   AXForum > Microsoft Dynamics CRM > Dynamics CRM: Разработка
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.03.2012, 23:56   #1  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Post Update Event “Generic Sql Error” crm 2011
Всем доброй ночи
Такая проблема
Если я пытаюсь сделать Retrieve либо RetrieveMultiple в Post Update например сущности контакт.
Падает со следующей ошибкой:
X++:
Message: Generic SQL error.
Stack Trace: 
Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.Xrm.Sdk.IOrganizationService.Retrieve(String entityName, Guid id, ColumnSet columnSet)
   at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.RetrieveCore(String entityName, Guid id, ColumnSet columnSet)
   at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Retrieve(String entityName, Guid id, ColumnSet columnSet)
Ошибка вываливается только, если выполняются два условия:
1. Использования сервиса из сборок MS.
2. Если ретрив направлен на туже сущность в плагине которой код находится.
(если плагин бежит на изменения контакта и ретрив тоже на контакт, тогда он падает)
Если я использую сервис из контекста ретривы срабатывают без проблем.
Тот же самый ретрив прекрасно срабатывает на Pre update/Pre Create/Post Create

Короче галиматья какая-та.

Ошибка в трейсе такая:
Взяв из ошибки запрос и запустив его в SQL Management Studio срабатывает без проблем
X++:
Exception when executing query: select 
"contact0".FullName as "fullname"
, "contact0".ContactId as "contactid"
, "contact0".OwningBusinessUnit as "owningbusinessunit"
, "contact0".OwningUser as "owninguser"
, "contact0".OwnerId as "ownerid"
, "contact0".OwnerIdType as "owneridtype" 
from
 Contact as "contact0" 
where
 ("contact0".ContactId = 'ef08d04f-a417-e111-bbcc-000c2977cd58') Exception: System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at Microsoft.Crm.CrmDbConnection.InternalExecuteWithRetry[TResult](Func`1 ExecuteMethod, IDbCommand command)
   at Microsoft.Crm.CrmDbConnection.InternalExecuteReader(IDbCommand command, Boolean capturePerfTrace)
   at Microsoft.Crm.CrmDbConnection.ExecuteReader(IDbCommand command, Boolean impersonate, Boolean capturePerfTrace)
   at Microsoft.Crm.BusinessEntities.BusinessProcessObject.ExecuteQuery(CrmDbConnection dbConnection, IDbCommand command, ISqlExecutionContext context)
[2012-03-19 21:40:03.071] Process: w3wp |Organization:e5d0c6a5-4014-4eb1-b466-46876080e569 |Thread:   14 |Category: Platform.Sql |User: f350993d-7114-e111-9bcc-000c2977cd58 |Level: Error | BusinessProcessObject.DoRetrieve
>Exception when executing query: select 
"contact0".FullName as "fullname"
, "contact0".ContactId as "contactid"
, "contact0".OwningBusinessUnit as "owningbusinessunit"
, "contact0".OwningUser as "owninguser"
, "contact0".OwnerId as "ownerid"
, "contact0".OwnerIdType as "owneridtype" 
from
 Contact as "contact0" 
where
 ("contact0".ContactId = 'ef08d04f-a417-e111-bbcc-000c2977cd58') Exception: System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at Microsoft.Crm.CrmDbConnection.InternalExecuteWithRetry[TResult](Func`1 ExecuteMethod, IDbCommand command)
   at Microsoft.Crm.CrmDbConnection.InternalExecuteReader(IDbCommand command, Boolean capturePerfTrace)
   at Microsoft.Crm.CrmDbConnection.ExecuteReader(IDbCommand command, Boolean impersonate, Boolean capturePerfTrace)
   at Microsoft.Crm.BusinessEntities.BusinessProcessObject.ExecuteQuery(CrmDbConnection dbConnection, IDbCommand command, ISqlExecutionContext context)
   at Microsoft.Crm.BusinessEntities.BusinessProcessObject.DoRetrieve(BusinessEntityMoniker moniker, BusinessEntity entity, EntityExpression entityExpression, ExecutionContext context, Int32 languageCode, DatabaseQueryTarget queryTarget)

Такая же ситуация с плагином который написан под 4, если он бежит из под crm 2011.

Буду рад всем предложениям по поводу решения этой проблемы.

Заранее Благодарен Константин
__________________
Читайте SDK!!!
Старый 20.03.2012, 00:46   #2  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
Собственно я не очень понял Ваш вопрос.

Если я использую сервис из контекста ретривы срабатывают без проблем.

Значит нужно его использовать.

Теперь по поводу почему это происходит. И происходит именно так.
И Происходит именно так в CRM 2011

В CRM 2011 теперь плагины выполняются в транзакции.
В CRM есть след. шаги плагинов
10 PreOperation
20 PreValidation
30
40 PostOperation
50 PostOperation (deprecated)

Шаги 20 30 40 находятся в транзакции
В CRM 4 мы могли вешать плагин на 10 PreOperation и на 50 PostOperation
В CRM 2011 на 10 PreOperation, 20 PreValidation и 40(СОРОК) PostOperation

То есть любой плагин выполняется в транзакции.
Тепер что получается? Когда данные в транзакции и еще не сохранены в БД полностью Вы пытаетесь её считать. Вот у Вас и ошибка. Я это проверял при попытке считать из БД данные напрямую. Также проверял, что это работает если использовать веб-сервис из контекста плагина.

Еще можно попробовать повесить это все на асинхронную операцию. таким образом, когда данные будут сохранены и их можно будет считать, асинхронный плагин отвиснет и считает. С получением данных из БД это работало.

Напишите если это помогло.


В подтверждении своих слов нашёл у Вас следующее

The timeout period elapsed prior to completion of the operation

То есть представте, что Вы пишете в таблицу ContactBase и ContactExtantionBase. В этот самый момент данные еще не сохранены. и Вы тут же пытаетесь считать данные. При чем из другой транзакции. Естественно другая транзакция ждёт, когда Вы данные отпустите, а Вы их не отпускаете и ждете, когда другая транзакция их получит. Это явный DeadLock.

В результате TimeOut. Вот теперь это точно.

Последний раз редактировалось g.Naukovych; 20.03.2012 в 00:53.
За это сообщение автора поблагодарили: Konstantin Katsovich (2).
Старый 20.03.2012, 10:12   #3  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
Если я использую сервис из контекста ретривы срабатывают без проблем.
Значит нужно его использовать.
Я подумаю о Вашем предложении. только что делать с кодом который уже написан под 4. (см. ниже)

Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
То есть любой плагин выполняется в транзакции.
Тепер что получается? Когда данные в транзакции и еще не сохранены в БД полностью Вы пытаетесь её считать. Вот у Вас и ошибка. Я это проверял при попытке считать из БД данные напрямую. Также проверял, что это работает если использовать веб-сервис из контекста плагина.
Странно
Если использовать веб-сервис из контекста плагина у меня ошибка не вываливается.

Остается ещё очень много вопросов, которые все вместе не дают полную картину.
Рочему в Post Create (40) этого не происходит?

Теперь перейдем в плагину написаному для четверки который падает по той же причине.
50 stage уже не находится в транзакции почему тогда он тоже падает?
Он поддерживается?
Или получается код который написан под 4 не обязательно будет бежать на том же stage в 2011.
(галиматья какая-та)

P. S. Предыдущий программист который писал этот плагин использовал References на веб сервис для удобства работы с сущностями. теперь если переделывать его плагин на сервис из контектста придется переписывать весь код.
P. S. Теперь нельзя делать ретривы в Post Update при использовании сборок либо References на веб сервис.
__________________
Читайте SDK!!!
Старый 20.03.2012, 10:23   #4  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
Я видимо неправильно выразился.
Если вызывать веб-сервис из контекста, то работать должно. Это работает и у меня и у Вас.

Цитата:
Теперь перейдем в плагину написаному для четверки который падает по той же причине.
50 stage уже не находится в транзакции почему тогда он тоже падает?
Он поддерживается?
Шаг 50 запрещён. На него нельзя зарегистрировать плагин.

Тут еще тонкий момент. Вы наверного обращаетесь к crmService. Это способ работы с CRM4
В CRM 2011 рекомендуется работать с OrganizationService

Цитата:
P. S. Предыдущий программист который писал этот плагин использовал References на веб сервис для удобства работы с сущностями. теперь если переделывать его плагин на сервис из контектста придется переписывать весь код.
И еще в SDK есть программа, которая генерирует прокси-классы на основе текущего состояния кастомизации. Можно воспользоваться ею, сгенерировать cs файл, включить его в плагин.


Цитата:
P. S. Теперь нельзя делать ретривы в Post Update при использовании сборок либо References на веб сервис.
Видимо запрос из другой транзакции невозможен.
Старый 20.03.2012, 11:28   #5  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
Шаг 50 запрещён. На него нельзя зарегистрировать плагин.
Он не запрешен
Если Вы делаете перенос проекта с 4 на 2011 и у вас там есть плагины именно на него (50) и нужно их вешать.
Конечно же нельзя плагин неписаный под 2011 повешать на этот евент. Plugin Registration вам этого не даст

Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
Тут еще тонкий момент. Вы наверного обращаетесь к crmService. Это способ работы с CRM4
В CRM 2011 рекомендуется работать с OrganizationService
А за объектом OrganizationService в конечном итоге тоже стоит сервис который называется умным словом WCF. Замена crmService для 2011. (со своими новыми возможностями)
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
И еще в SDK есть программа, которая генерирует прокси-классы на основе текущего состояния кастомизации. Можно воспользоваться ею, сгенерировать cs файл, включить его в плагин.
это существует для crm 2011, а не для crm 4. (Плагин написан под crm 4)
__________________
Читайте SDK!!!
Старый 20.03.2012, 11:44   #6  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
В любом случае плагин не работает на шаге 50, даже если он на него мигрировал.

Можно сделать еще ё вариант, не уверен попойдёт ли он Вам. Плагин повесить на шаг 10. КОгда еще нет транзакции. На основе PreImage и таргет сформировать PostImage.
Потом вызвать Вашу операцию и заменить там значение, которое получилось у той записи, что вы изменили на значение из PostImage.

Или еще 1 вариант переведите плагин в асинхронных режим. То есть когда Вы будете обращаться к списку записей у Вас уже будет не DeadLock, а просто Lock. Вы проиграете по времени в вычислениях, данные не будут приходить сразу же, но при этом они все равно изменятся и Вам не придётся переписывать плагин.
Старый 20.03.2012, 11:57   #7  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
В любом случае плагин не работает на шаге 50, даже если он на него мигрировал.
Работает работает и еще как работает.
Можно даже его менять и он снова работает.

P. S. А за варианты спасибо
__________________
Читайте SDK!!!
Старый 20.03.2012, 12:00   #8  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
а Как Вы транзакцию побороли?

А если в него зайти и шаг посмотреть там 50 написано?
Старый 20.03.2012, 12:10   #9  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
а Как Вы транзакцию побороли?
Я видимо переделаю плагин на DynamicEntity в том же самом stage и буду использовать сервис контекста.
Не хочу изобретать велосипед

Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
А если в него зайти и шаг посмотреть там 50 написано?
Да 50
__________________
Читайте SDK!!!
Старый 20.03.2012, 12:13   #10  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
В CRM 2011 вместо DynamicEntity есть просто Entity. С ними немного удобнее работать
Старый 21.03.2012, 02:43   #11  
Артем Enot Грунин is offline
Артем Enot Грунин
Moderator
Аватар для Артем Enot Грунин
MCBMSS
Злыдни
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,912 / 623 (28) +++++++
Регистрация: 16.08.2007
Адрес: Пермь!
Записей в блоге: 151
Ваша проблема связанна именно с транзакционностью плагинов CRM 2011. В SDK по этому поводу даже есть несколько строк:
Access to the Organization Service

To access the Microsoft Dynamics CRM organization service, it is required that plug-in code create an instance of the service through the ServiceProvider.GetService method.
C# Copy Code // Obtain the organization service reference. IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
The platform provides the correct Web service URLs and network credentials for you when you use this method. Instantiating your own Web service proxy is not supported as it will create deadlock and authentication issues.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия.

MS Certified Dirty Magic Professional
За это сообщение автора поблагодарили: Konstantin Katsovich (1).
Старый 21.03.2012, 10:28   #12  
Konstantin Katsovich is offline
Konstantin Katsovich
Участник
Аватар для Konstantin Katsovich
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
243 / 57 (2) ++++
Регистрация: 22.10.2008
Адрес: Israel
Цитата:
Сообщение от Артем Enot Грунин Посмотреть сообщение
Ваша проблема связанна именно с транзакционностью плагинов CRM 2011. В SDK по этому поводу даже есть несколько строк:
Access to the Organization Service

To access the Microsoft Dynamics CRM organization service, it is required that plug-in code create an instance of the service through the ServiceProvider.GetService method.
C# Copy Code // Obtain the organization service reference. IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
The platform provides the correct Web service URLs and network credentials for you when you use this method. Instantiating your own Web service proxy is not supported as it will create deadlock and authentication issues.
Видимо по той же причине начал падать четверешный плагин.

P. S. странно я поставил 5
__________________
Читайте SDK!!!

Последний раз редактировалось Konstantin Katsovich; 21.03.2012 в 10:33. Причина: добавление "P.S."
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Microsoft Dynamics CRM Team Blog: Introduction to the Microsoft Dynamics CRM November 2011 service update Blog bot Dynamics CRM: Blogs 0 02.11.2011 04:17
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 4 Blog bot Dynamics CRM: Blogs 0 24.09.2011 01:16
Microsoft Dynamics CRM Team Blog: Update Rollup 4 for Microsoft Dynamics CRM 2011 Blog bot Dynamics CRM: Blogs 0 22.09.2011 20:11
crminthefield: Microsoft Dynamics CRM 4.0 and 2011 Update Rollup Release Dates, Build Numbers, and Collateral Blog bot Dynamics CRM: Blogs 0 24.08.2011 02:11
Microsoft Dynamics CRM Team Blog: Microsoft Dynamics CRM 2011 ~ Online Test Drive Guide Blog bot Dynamics CRM: Blogs 0 05.08.2011 20:13

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 08:25.