Compartir por


Diseño de personalización escalable: ejemplo de numeración automática

Nota:

En este ejemplo se apoyan una serie de temas relacionados con el diseño de personalización escalable. Para empezar al principio, consulte Diseño de personalización escalable en Microsoft Dataverse.

Dataverse cuenta con una característica de columnas de numeración automática que debe usar si cumple con sus requisitos.

En este artículo se describe cómo administrar transacciones de forma eficaz para garantizar que una solución pueda controlar el crecimiento mediante el ejemplo de numeración automática. Detalla un proceso de intentar, probar y evaluar diferentes enfoques. Aunque el tercer enfoque mejora los dos primeros, es posible que no sea perfecto para cada situación. Por lo tanto, es fundamental probar exhaustivamente cualquier solución desarrollada, ya que es responsable de mantener su propio código.

Un escenario que ilustra el malentendido común de cómo se controlan las transacciones dentro de Dataverse está implementando un esquema de numeración automática.

En este escenario, el requisito suele ser:

  • Genere un número único siguiendo un patrón determinado.
  • Permitir que muchas solicitudes simultáneas creen el tipo relacionado de registros; por ejemplo, las cuentas que necesitan una referencia única.
  • Permite la numeración secuencial de los números únicos.
  • Asegúrese de que la generación de números sea coherente, pero escalable y no produzca errores en la carga. También debe asegurarse de que no se pueden generar números duplicados.
  • Genere el número al crear el registro correspondiente.

El enfoque típico implica variaciones de lo siguiente:

  • Almacene el último número usado en un almacén de datos de índice de número automático; por ejemplo, una entidad personalizada con una fila por tipo de datos.
  • Recupere el último número usado e incremente ese número.
  • Registre el nuevo número en el registro recién generado.
  • Vuelva a almacenar el nuevo número como el último número utilizado en el almacén de indexado automático de números.

En las secciones siguientes se describen distintos enfoques que se pueden tomar en Dataverse y se resaltan las implicaciones, lo que muestra la importancia y la ventaja de comprender la forma en que se usan las transacciones.

Enfoque 1: Fuera de una transacción

El enfoque más sencillo consiste en darse cuenta de que cualquier uso de un recurso necesario habitualmente introduciría la posibilidad de bloqueo. Dado que el bloqueo tiene un impacto en la escalabilidad, puede decidir que desea evitar una transacción de plataforma al generar un número automático. Consideremos el escenario de generación de numeración automáticamente fuera de transacciones de canalización en un complemento antes de la validación.

Método 1: Fuera de una transacción.

Cuando se ejecuta de forma aislada, funciona bien. Sin embargo, no protege realmente frente a errores de simultaneidad. Como se muestra en el diagrama siguiente, si dos solicitudes en paralelo solicitan el número más reciente y, a continuación, incrementan y actualizan el valor, terminará con números duplicados. Puesto que no hay bloqueos para el número recuperado, es posible que se produzca una condición race y que ambos subprocesos acaben tiendo el mismo valor.

condición de carrera.

En muchos casos, aunque se produzcan muchas solicitudes, debido al margen de superposición limitado, esto podría funcionar bien, pero se trataría de suerte en lugar de un buen diseño para evitar duplicados.

Enfoque 2: En una transacción de complemento

Si realiza la numeración automática desde un complemento registrado dentro de la transacción (txn), esto seguramente funcionará... ¿verdad?

Método 2: Dentro de una transacción de complementos.

En las mismas circunstancias de las solicitudes superpuestas que intentan generar números al mismo tiempo, sería posible conceder a ambas solicitudes un bloqueo de lectura compartido en la tabla de numeración automática. Desafortunadamente, en el momento en que la aplicación intenta actualizar esto a un bloqueo exclusivo, esto no sería posible, ya que habría otro bloqueo de lectura compartido que impida esto.

el bloqueo de lectura compartido impide el acceso.

Dependiendo de cómo se generan las consultas, el comportamiento exacto puede variar, pero confiar en esas condiciones y no estar seguro del resultado en el que la unicidad es esencial no es ideal. Aunque esto no genere un error, la capacidad de lectura compartida podría permitir que se genere un número duplicado si los modos de aislamiento no son correctos. Como se muestra en el diagrama siguiente, ambos registros terminan con el mismo valor de número automático de 8.

ambos registros terminan con el mismo valor de número automático.

Enfoque 3: Bloqueo previo en una transacción de complemento

Comprender la forma en que funcionan las transacciones conduce a poder generar una manera segura de hacerlo.

En este método, desde el principio de la transacción, se realiza una actualización del marcador en el registro de numeración automática a algún campo determinado (por ejemplo, UpdateInProgress), que se utiliza simplemente con el fin de mantener la coherencia. Para ello, escribe una actualización que indica que una actualización está a punto de iniciarse. A continuación, este proceso solicita y toma un bloqueo de escritura exclusivo en esa fila de la tabla de numeración automática, lo que impide que otros procesos inicien el enfoque de numeración automática.

A su vez, esto le permite aumentar y volver a escribir de forma segura la numeración automática actualizada sin que puedan interferir otros procesos.

Enfoque 3: Bloquear previamente una transacción de complemento.

Tiene la implicación de que esto serializará no solo las actualizaciones de numeración automática, sino también las solicitudes de creación de cuentas, ya que ambos pasos se producen en la misma transacción de plataforma. Si la creación de cuentas es rápida, puede ser perfectamente un método válido y garantiza que la creación de la cuenta y la numeración automática se ejecutan de forma sistemática; si se produce un error en uno de los procesos, ambos fallarán y se revertirán.

De hecho, cuando las demás acciones dentro de la transacción son rápidas, este es el enfoque más coherente y eficaz para implementar la numeración automática en personalizaciones.

Sin embargo, si también introduce otros complementos o flujos de trabajo sincrónicos que cada uno tardan grandes cantidades de tiempo en completarse, la serialización puede convertirse en un desafío real de escalabilidad, ya que el proceso de numeración automática no solo se bloquea, sino que se bloquea a la espera de que se completen las demás actividades.

El proceso de numeración automática no solo se bloquea, sino que bloquea la espera de que se completen las demás actividades.

Normalmente, la generación de la numeración automática se realizará en un complemento anterior al evento. Debe incluir el número en los parámetros de entrada para el paso de creación y evitar una segunda actualización en el procesamiento posterior para registrar el número que se generó automáticamente en la cuenta.

Teniendo en cuenta las implicaciones de escalabilidad, si hay otro procesamiento complejo en el proceso de creación de la cuenta, una alternativa sería mover la generación de números automáticos a un proceso posterior a la creación, lo que garantiza un proceso de actualización coherente. La ventaja sería que reduce el tiempo dentro de la transacción durante el que se retiene el bloqueo de registro de numeración automática ya que el bloque se pasa al final del proceso. Si la tabla de numeración automática es el recurso más disputado y se adopta este enfoque para todos los procesos que acceden a ella, esto reduce la disputa en general.

El inconveniente aquí sería la necesidad de realizar otra actualización para la cuenta, a la vez que se reduce el tiempo total de bloqueo en espera del registro de numeración automática.

mueva la generación de números automáticos a un proceso posterior a la creación.