Compartir por


Diseño de personalización escalable: transacciones de base de datos

Nota:

Este es el segundo de una serie de temas sobre el diseño de personalización escalable. Para empezar al principio, consulte Diseño de personalización escalable en Microsoft Dataverse.

Uno de los conceptos más fundamentales que hay detrás de muchos de los desafíos que se enfrentan aquí es el de la transacción de base de datos. En Dataverse, la base de datos está en el centro de casi todas las solicitudes al sistema y la coherencia de los datos de lugar se aplica principalmente.

  • Ninguna operación de datos de Dataverse, ya sea interna o parte de personalizaciones de código, funciona completamente de forma aislada.
  • Todas las operaciones de datos de Dataverse interactúan con los mismos recursos de base de datos, ya sea en un nivel de datos o en un nivel de infraestructura, como el uso de procesador, memoria o E/S.
  • Para protegerse frente a los cambios conflictivos, cada solicitud bloquea recursos para poder verse o modificarse.
  • Esos bloqueos se toman dentro de una transacción y no se liberan hasta que la transacción se confirma o anula.

Conocimiento de transacciones y bloqueos

Una razón común por la que pueden producirse problemas en esta área es la falta de conocimiento de cómo las personalizaciones pueden afectar a las transacciones.

Aunque los detalles de cómo se hace están fuera del ámbito de este artículo, el elemento más sencillo que se debe tener en cuenta es que, a medida que Dataverse interactúa con los datos de su base de datos. SQL Server determina los bloqueos correctos que las transacciones aplican sobre esos datos, como:

  • Al crear un registro, genera un bloqueo de escritura en ese registro.
  • Cuando se actualiza un registro, se aplica un bloqueo de escritura en el registro.
  • Cuando un bloqueo se aplica en una tabla o un registro, también se aplicará en los registros de índice correspondientes.

Sin embargo, es posible influir en el ámbito y la duración de estos bloqueos. También es posible indicar a SQL Server que no se requiere ningún bloqueo para determinados escenarios.

Consideremos el bloqueo de la base de datos de SQL Server y el impacto de las solicitudes independientes que intentan acceder a los mismos datos. En el ejemplo siguiente, la creación de una cuenta ha configurado una serie de procesos, algunos con complementos que se desencadenan en cuanto se crea el registro y algunos en un flujo de trabajo asincrónico relacionado que se inicia en la creación.

En el ejemplo se muestran las consecuencias cuando un proceso de actualización de cuenta tiene un procesamiento posterior complejo, mientras que otra actividad también interactúa con el mismo registro de cuenta. Si se procesa un flujo de trabajo asincrónico mientras la transacción de actualización de la cuenta sigue en curso, este flujo de trabajo podría bloquearse esperando a obtener un bloqueo de actualización para cambiar el mismo registro de cuenta, que todavía está bloqueado.

Ejemplo de bloqueo y transacciones.

Debe tenerse en cuenta que las transacciones solo se mantienen dentro de la vigencia de una solicitud determinada a la plataforma. Los bloqueos no se mantienen a nivel de sesión de usuario ni tampoco mientras la información se muestra en la interfaz del usuario. Tan pronto como la plataforma haya completado la solicitud, libera la conexión de la base de datos, la transacción relacionada y cualquier bloqueo que haya tomado.

Bloqueos

Aunque el tipo de bloqueo en el ejemplo anterior puede ser inconveniente en sí mismo, este bloqueo también puede provocar consecuencias más graves cuando se considera que Dataverse es una plataforma que puede procesar cientos de acciones simultáneas. Aunque mantener un bloqueo en un registro de cuenta individual puede tener implicaciones razonablemente limitadas, ¿qué ocurre cuando un recurso es más fuertemente impugnado?

Por ejemplo, cuando a cada cuenta se le asigna un número de referencia único, podría dar lugar a que un único recurso que realiza el seguimiento de los números de referencia utilizados sea bloqueado por cada uno de los procesos de creación de cuentas. Como se describe en el ejemplo de numeración automática, si se generan muchas cuentas en paralelo, todas las solicitudes superpuestas necesitan acceder a ese recurso de numeración automática y bloquearlo hasta que completen su acción. Cuanto más tiempo tarde cada proceso de creación de cuentas, y cuantos más solicitudes simultáneas haya, más bloqueo se produce.

Mientras que la primera solicitud que logre el bloqueo de recurso de numeración automática se completará fácilmente, la segunda solicitud necesita esperar a que finalice la primera para poder comprobar cuál es el siguiente número de referencia único. La tercera solicitud tiene que esperar a que se completen las solicitudes primera y segunda. Cuantas más solicitudes haya, más se prolonga el bloqueo. Si hay suficientes solicitudes, y cada una dura bastante, ese retraso puede impulsar las solicitudes posteriores hasta tal punto que se agote el tiempo de espera, aunque individualmente se puedan completar correctamente.

ejemplo de bloqueo.

Liberación de bloqueo

Hay dos razones principales por las que no se libera un bloqueo, pero se mantiene hasta que se completa la transacción:

  • El servidor de bases de datos mantiene el bloqueo por coherencia en caso de que la transacción posteriormente realice otra solicitud para actualizar los datos.
  • El servidor de base de datos también debe tener en cuenta que un comando de error o de aborto emitido más adelante puede hacer que revierta toda la transacción, por lo que necesita mantener los bloqueos durante toda la duración de la transacción para garantizar la coherencia.

Es importante reconocer que, aunque el proceso haya completado cualquier interacción con un fragmento de datos determinado, el bloqueo se mantiene hasta que se complete y confirme toda la transacción. Cuanto más larga se extienda la transacción, más tiempo se mantiene el bloqueo, lo que impide que otros subprocesos interactúen con esos datos. Como se muestra más adelante, esto también incluye personalizaciones relacionadas que funcionan dentro de la misma transacción y pueden ampliar significativamente la duración de las transacciones, como flujos de trabajo sincrónicos.

En el siguiente ejemplo, el bloqueo de escritura en una entidad personalizada en el complemento previo a la creación para una cuenta está bloqueado hasta que toda la lógica ligada a la creación de la cuenta se complete.

liberación de bloqueo.

Errores intermitentes: tiempo

El comportamiento intermitente es un síntoma obvio del bloqueo de la actividad simultánea. Si repetir exactamente la misma acción más adelante tiene éxito cuando anteriormente falló, hay una fuerte probabilidad de que el error o la lentitud fueran causados por otro factor concurrente.

Es importante entender que la depuración de un problema suele implicar reducir la funcionalidad problemática al mínimo. Sin embargo, cuando el problema solo se produce de forma intermitente, es posible que tenga que ver dónde entra en conflicto la acción con error con otra actividad en el sistema y debe examinar los posibles puntos de contención. Puede mitigar el conflicto mediante la optimización de un proceso individual; sin embargo, cuanto menor sea el tiempo de procesamiento, menos probable es que la actividad entre en conflicto con otros procesos.

Control de transacciones

Aunque en la mayoría de los casos se pueden dejar las transacciones a la plataforma para administrar, hay escenarios en los que la lógica necesaria es lo suficientemente compleja que es necesario comprender e influir en las transacciones para lograr los resultados deseados. Dataverse ofrece muchos enfoques de personalización diferentes que afectan de forma diferente a la forma en que se usan las transacciones.

Cuando comprenda cómo participa cada tipo de personalización en las transacciones de la plataforma, puede modelar escenarios complejos de forma eficaz en Dataverse y predecir su comportamiento.

Como se mencionó anteriormente, una transacción solo se mantiene durante la vigencia de una solicitud a la plataforma, no es algo que se mantiene una vez completado el paso de la plataforma. Esta duración limitada evita que un cliente externo mantenga las transacciones durante largos períodos y bloquee otras actividades de la plataforma.

El trabajo de la plataforma es mantener la coherencia en toda la canalización de transacciones de la plataforma y, cuando corresponda, permitir que las personalizaciones participen en esa misma transacción.

Cómo usan las aplicaciones controladas por modelos las transacciones

Antes de comprender cómo interactúan las personalizaciones con la plataforma, resulta útil comprender cómo las aplicaciones controladas por modelos usan solicitudes a la plataforma y cómo afecta al uso de transacciones.

Operation Description
Formularios (recuperar) • Bajo impacto en otros usos.
Create • Realiza una solicitud de creación a través de la plataforma
• Bajo impacto en otras actividades, ya que un nuevo registro no debe tener nada que lo bloquee.
• Potencialmente puede bloquear consultas con bloqueo para la totalidad de la tabla hasta que se complete.
• A menudo puede desencadenar acciones relacionadas en la personalización que pueden tener un impacto.
Update • Realiza una solicitud de actualización a través de la plataforma.
• Es más probable que tenga conflictos. Un bloqueo de actualización bloquea cualquier otra actualización de ese registro.
• A menudo desencadena otras actividades.
• En algunos casos excepcionales, un bloqueo de actualización puede bloquear un bloqueo de lectura. Un ejemplo de dónde puede ocurrir es cuando se cambian los metadatos de Dataverse: las lecturas realizadas por una transacción de cambio de metadatos de Dataverse se bloquearán mediante bloqueos de actualización.
Vista (RetrieveMultiple) • Bajo impacto en otros usos.
• Las consultas con un pobre rendimiento pueden sobrecargar los recursos de la base de datos y alcanzar los límites de tiempo de espera.

Canalización de eventos: etapa de plataforma

Cuando se inicia una canalización de eventos, se crea una transacción SQL para incluir el paso de la plataforma. Esto garantiza que toda la actividad de base de datos realizada por la plataforma actúe de forma coherente. La transacción se crea al principio de la canalización de eventos y se confirma o anula cuando se completa el procesamiento, en función de si se realizó correctamente.

paso de la plataforma en la canalización de eventos.

Solicitudes de personalización

También es posible participar en la transacción iniciada por la plataforma dentro de las personalizaciones. Cada tipo de personalización participa en transacciones de una manera diferente. Las secciones siguientes describen cada una de ellas a su vez.

Sincronización de complementos (operación previa o posterior: en contexto de transacción)

Cuando los complementos se registran para un evento, se pueden registrados en una etapa PreOperation o PostOperation que esté dentro de la transacción. Las solicitudes de mensaje del complemento se realizan dentro de la transacción. Esto significa que la duración de la transacción y los bloqueos aplicados, se ampliarán.

Sincronización de complementos (operación previa o posterior: en contexto de transacción).

Sincronización de complementos (operación previa y posterior: en contexto de transacción)

Los complementos pueden registrarse en las etapas PreOperation y PostOperation. En este caso, la transacción puede extenderse aún más porque se extiende desde el inicio del complemento PreOperation hasta que se complete el complemento PostOperation .

Sincronización de complementos (operación previa y posterior: en contexto de transacción).

Complementos de sincronización (PreValidation: fuera del contexto de transacción)

También se puede registrar un complemento para actuar fuera de la transacción de la plataforma si se registra en la fase PreValidation .

Nota:

No crea su propia transacción. Como resultado, cada solicitud de mensaje dentro del complemento se actúa de forma independiente dentro de la base de datos.

Complementos de sincronización (Prevalidación: fuera del contexto de transacción).

Este escenario se aplica solo cuando se invoca PreValidation como la primera etapa de un evento de la canalización. Aunque el complemento está registrado en la fase PreValidation , es posible que participe en una transacción como se describe en la sección siguiente. No se puede suponer que un complemento PreValidation no participa en una transacción, aunque es posible comprobar desde el contexto de ejecución si este es el caso.

Complementos de sincronización (PreValidation: en el contexto de la transacción)

El escenario relacionado se produce cuando se registra un complemento PreValidation, pero la solicitud de mensaje desencadena el evento de canalización relacionado dentro de una transacción existente.

Como se muestra en el diagrama siguiente, la creación de una cuenta puede hacer que un complemento PreValidation se realice inicialmente fuera de una transacción cuando se realiza la creación inicial. Si, como parte del complemento posterior, una solicitud de mensaje se realiza para crear una cuenta secundaria relacionada porque esa segunda canalización de eventos se inicia desde dentro de la canalización principal, participa en la misma transacción.

En ese caso, el complemento PreValidation detecta que ya existe una transacción y, por tanto, participa en esa transacción aunque esté registrada en la fase PreValidation .

Complementos de sincronización (PreValidation: en el contexto de la transacción).

Como se mencionó anteriormente, el complemento puede comprobar el contexto de ejecución de la IsInTransaction propiedad , que indica si este complemento se está realizando dentro de una transacción o no.

Complementos asincrónicos

Un complemento también se puede registrar para actuar de forma asincrónica. En este caso, el complemento también actúa fuera de la transacción de la plataforma.

Nota:

El complemento no crea su propia transacción; Cada solicitud de mensaje dentro del complemento se actúa de forma independiente.

foo.

Resumen del uso de transacciones del complemento

Resumiendo:

  • Los complementos sincrónicos suelen participar en transacciones.
  • Los complementos asincrónicos nunca participan en una transacción de plataforma; cada solicitud se realiza de forma independiente.
  • Los complementos preValidation no crean una transacción, pero participan si ya existe una.
Event Nombre de la fase La transacción aún no existe La transacción ya existe
Evento previo Prevalidación No se crea ninguna transacción. No participa en la transacción; cada solicitud usa transacciones independientes para la base de datos Participa en la transacción existente
Evento previo PreOperation Participa en la transacción existente Participa en la transacción existente
Posterior al evento PostOperation Participa en la transacción existente Participa en la transacción existente
Async N/A No se crea ninguna transacción. No participa en la transacción; cada solicitud usa transacciones independientes para la base de datos N/A

Flujos de trabajo sincrónicos

Desde la perspectiva de las transacciones, los flujos de trabajo sincrónicos actúan como complementos previos y posteriores a la operación. Por lo tanto, actúan dentro de la transacción de canalización de la plataforma y pueden tener el mismo efecto en la longitud de la transacción global.

Flujos de trabajo sincrónicos.

Flujos de trabajo asincrónicos

Los flujos de trabajo asincrónicos se desencadenan fuera de la transacción de la plataforma.

Nota:

El flujo de trabajo tampoco crea su propia transacción y, por tanto, cada solicitud de mensaje dentro del flujo de trabajo se actúa de forma independiente.

En el diagrama siguiente se muestra el flujo de trabajo asincrónico que actúa fuera de la transacción de la plataforma y cada paso iniciando su propia transacción independiente.

Flujos de trabajo asincrónicos.

Actividad de flujo de trabajo personalizada

Las actividades de flujo de trabajo personalizadas actúan dentro del contexto de flujo de trabajo primario.

  • Flujo de trabajo de sincronización: actúa dentro de la transacción
  • Flujo de trabajo asincrónico: actúa fuera de la transacción

En el diagrama siguiente se muestran las actividades personalizadas que actúan primero dentro de un flujo de trabajo sincrónico y, a continuación, dentro de un flujo de trabajo asincrónico.

Actividad de flujo de trabajo personalizada.

Acciones personalizadas

Las acciones personalizadas pueden crear sus propias transacciones. Se trata de una característica clave. Una acción personalizada puede crear una transacción independiente fuera del paso de la plataforma en función de si está configurada para habilitar la reversión.

  • Habilitar reversión establecido
    • Si se invoca a través de solicitud de mensaje desde un complemento que se ejecuta dentro de la transacción, y está establecido Habilitar reversión, la acción personalizada se desarrolla en la transacción existente.
    • De lo contrario, la acción personalizada crea una nueva transacción y se ejecuta dentro de eso.
  • Habilitar reversión no establecido
    • La acción personalizada no actuará dentro de una transacción.

acciones personalizadas.

Solicitudes de servicio web

Cuando las solicitudes se realizan externamente a través de servicios web, se crea una canalización y el control de transacciones dentro de la canalización se produce como se explicó anteriormente, pero una transacción no se mantiene una vez que se devuelve la respuesta. Dado que no se sabe cuánto tiempo falta para la próxima solicitud, la plataforma no permite bloquear recursos que impedirían otras actividades.

Cuando se realizan varias solicitudes dentro de un complemento con el mismo contexto de ejecución, es el contexto de ejecución común que mantiene la referencia de transacción y en complementos sincrónicos garantiza que cada solicitud se realice dentro de la misma transacción. La capacidad de mantener un contexto de ejecución entre las solicitudes no está disponible fuera de los complementos y, por tanto, no se puede mantener una transacción entre solicitudes independientes realizadas externamente.

Hay dos mensajes especiales en los que se pueden pasar varias acciones a la plataforma de Dataverse como parte de una única solicitud de servicio web.

Message Description
ExecuteMultiple Esto permite pasar varias acciones independientes dentro de la misma solicitud de servicio web. Cada una de estas solicitudes se realiza de forma independiente dentro de la plataforma, por lo que no hay ningún contexto de transacción mantenido entre las solicitudes.
ExecuteTransaction Esto permite procesar varias acciones dentro de la misma transacción de base de datos, de forma similar a varias solicitudes de mensajes realizadas desde dentro de un complemento sincrónico.

Esta capacidad también tendría implicaciones similares a varias solicitudes de mensajes; es decir, si cada acción tarda mucho tiempo (por ejemplo, realizando consultas costosas o desencadenando una larga cadena de complementos o flujos de trabajo sincrónicos relacionados), esto podría provocar problemas de bloqueo en la plataforma más amplia.

Solicitudes de API web (OData) en complementos

No use las solicitudes de API web (OData) dentro de un complemento a la misma organización que el complemento. Use siempre los IOrganizationService métodos . Esto hace posible que el contexto de la transacción se pase para que la operación pueda participar en la transacción de la canalización.

Pasos siguientes

Además de las transacciones de base de datos, es importante apreciar el impacto de varias operaciones de datos simultáneas en el sistema. Más información: Diseño de personalización escalable: cuestiones de concurrencia