Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
Categoría: Uso, Confiabilidad, Rendimiento
Potencial de impacto: Medio
Síntomas
Las experiencias de los usuarios se degradan y pueden producirse errores de tiempo de espera cuando se utilizan tipos de solicitudes por lotes en complementos y actividades de flujo de trabajo que se producen dentro de operaciones sincrónicas.
Las siguientes clases de solicitud de mensaje se consideran tipos de solicitud por lotes porque realizan operaciones en varios registros dentro de una sola solicitud:
- ExecuteMultipleRequest
- ExecuteTransactionRequest
- CreateMultipleRequest
- UpdateMultipleRequest
- UpsertMultipleRequest
Orientación
Use estos mensajes por lotes en aplicaciones cliente para realizar operaciones en varios registros. No use estos mensajes dentro del código que Dataverse invoca durante la ejecución de otra operación: una actividad de complemento o flujo de trabajo registrada para un paso sincrónico.
Más concretamente, úselas en los escenarios siguientes:
Use ExecuteMultipleRequest para cargar datos de forma masiva o procesos externos que tengan la intención de ejecutar operaciones de larga duración (más de dos minutos).
Use ExecuteMultipleRequest para minimizar los recorridos de ida y vuelta entre el cliente personalizado y los servidores de Dataverse, para reducir la latencia acumulativa en la que se incurre.
Utilice ExecuteTransactionRequest para los clientes externos que requieren que el lote de operaciones se confirme como una única transacción de base de datos atómica o se realice un rollback si se encuentra alguna excepción. Tenga en cuenta la posibilidad de bloqueo de la base de datos en la transacción prolongada.
Use mensajes de operación masiva (CreateMultipleRequest, UpdateMultipleRequesty UpsertMultipleRequest) para los mismos escenarios y para lograr un mayor nivel de rendimiento.
Patrones problemáticos
En el ejemplo siguiente se muestra el uso ExecuteMultipleRequest en el contexto de un complemento.
Advertencia
Este escenario debe evitarse.
public class ExecuteMultipleRequestInPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
QueryExpression query = new QueryExpression("account")
{
ColumnSet = new ColumnSet("accountname", "createdon"),
};
//Obtain the results of previous QueryExpression
EntityCollection results = service.RetrieveMultiple(query);
if (results != null && results.Entities != null && results.Entities.Count > 0)
{
ExecuteMultipleRequest batch = new ExecuteMultipleRequest();
foreach (Entity account in results.Entities)
{
account.Attributes["accountname"] += "_UPDATED";
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.Target = account;
batch.Requests.Add(updateRequest);
}
service.Execute(batch);
}
else return;
}
}
Este ejemplo incluye el uso del tipo directamente con el método Execute. El uso puede darse en cualquier lugar dentro del contexto de la ejecución de actividad de un complemento o flujo de trabajo. Esto puede estar en un método que esté incluido en la misma clase o en una clase independiente. No se limita a que se contenga directamente en la definición del Execute método.
Información adicional
El propósito del ExecuteMultiple mensaje es minimizar los recorridos de ida y vuelta entre el cliente y el servidor a través de conexiones de alta latencia. Los complementos se ejecutan directamente dentro del proceso de la aplicación o en las proximidades cuando están aislados en un entorno sandbox, lo que significa que la latencia rara vez representa un problema. El código del complemento debe centrarse en las operaciones que se ejecutan rápidamente y minimizan el bloqueo para evitar superar los umbrales de tiempo de espera y garantizar un sistema dinámico para escenarios sincrónicos. Envíe cada solicitud directamente en lugar de procesarlas por lotes y envíelas como una sola solicitud.
Por ejemplo: foreach (request in requests) service.Execute(request)
En el lado servidor, las operaciones incluidas en una solicitud por lotes se ejecutan secuencialmente y no se realizan en paralelo. Este es el caso incluso si la propiedad ExecuteMultipleSettings.ReturnResponses está establecida en false. Los desarrolladores tienden a usar solicitudes por lotes de esta manera, suponiendo que permite el procesamiento paralelo. Las solicitudes por lotes no logran este objetivo.
Las personas usan ExecuteTransactionRequest para asegurarse de que cada operación se incluye en una transacción. Esto no es necesario en un paso de complemento sincrónico porque el complemento ya se está ejecutando en el contexto de una transacción de base de datos, negando la necesidad de usar el ExecuteTransaction mensaje.
Consulte también
Marco de trabajo de eventos
Limitaciones en tiempo de ejecución
Ejecución de varias solicitudes mediante el SDK para .NET
Ejecución de mensajes en una sola transacción de base de datos