Continuando con los artÃculos de tipo práctico y relacionados con la optimización que hemos venido publicando, vamos a seguir con un ejemplo de optimización de procesos.
Dentro del capÃtulo de optimización, como ya hemos indicado y aparece en el manual de optimización, al trabajar con transacciones grandes, en ocasiones puede ser interesante dividir éstas en procesos más concretos, más especÃficos, que dividan la transacción de tal manera que, en vez de hacer una gran transacción, realice un número discreto de transacciones, más pequeñas y controlables.
Vamos a ver las ventajas y un ejemplo.
Entre las ventajas de esta optimización se encuentran:
-
Una mejor gestión de la memoria: como las transacciones son más pequeñas, necesita menor cantidad y la libera de una forma más ágil.
-
Periodos menores de bloqueo en la modificación de los registros: durante la modificación de los registros se produce un bloqueo de los registros hasta finalizar la transacción -aunque, desde luego, no hay problema para las lecturas mientras tanto-. Este bloqueo temporal en la escritura se minimiza al realizar el proceso sobre un menor número de registros y liberar la lista más rápidamente.
-
Mejor gestión de las operaciones: en los casos que ha sido necesario parar el proceso no es necesario que se deshagan las operaciones anteriores y podemos continuar donde ha parado; también si hemos tenido que parar la transacción y deshacer, no se deshacen todas las operaciones del proceso si no únicamente las de la transacción en curso. En ambos casos, para continuar el proceso basta buscar la lista pendiente de procesar, por lo que minimizamos las consecuencias de ambos.
-
Mejor gestión de la comunicación VATP: por supuesto, al lanzar el proceso que transacciona podremos aprovechar para hacerlo en tercer plano, por lo que evitamos el envÃo y recepción de datos entre cliente y servidor, y por tanto agilizamos el proceso.
Si además de estas ventajas tenemos en cuenta que:
-
Podemos clarificar el código al dividir en distintos procesos las diferentes tareas a realizar.
-
Al ser procesos más ágiles y menos bloqueantes, permiten ser ejecutados mientras hay usuarios conectados aunque se trate de procesar grandes listados.
Esto nos lleva a pensar que presentaros un ejemplo de este tipo de optimización puede ser muy interesante. Ahà va:
Vamos a plantear un ejemplo muy sencillo pero que se puede complicar tanto como queramos. Partiremos de un sistema de facturación, que va recorriendo el listado de albaranes (órdenes, recibos o justificaciones de entrega, o aquello que en cada circunstancia se facture).
La primera forma de acometer el problema, y que muchas veces es suficiente para realizar la optimización, es agrupar las facturas por entidad, por fecha o por aquel elemento de agrupación que más nos interese o que mejor nos permita dividir el listado de pendientes de facturar y gestionar los pendientes.
El proceso que gestiona la lista de registros (VTALB-FAC) no transacciona, pero puede realizar los controles que sean necesarios incluyendo solicitudes de información al usuario, información que pasará por variables globales al proceso llamado en el servidor, que es el que realmente transacciona (VTALB-GEN-FAC).
Pero podemos encontrarnos un caso en el que no sea sencillo realizar agrupaciones que nos lleven a un número limitado de registros y que aún pudiendo agrupar, las transacciones siguen resultando grandes.
En ambos casos la técnica es simple: un proceso llamador en el que gestionamos la lista de registros con la que trabajamos y realizamos las preguntas necesarias al usuario, para lanzar un proceso por cada sublista de la lista inicial de registros, que es el que realmente transacciona.
La diferencia está en la forma de generar las sublistas. En el primer caso hacemos uso únicamente del comando de instrucción de proceso: Multipartir lista, muy útil para estas tareas, que genera una sublista por cada agrupación de registros con el mismo valor en el campo seleccionado.
En el segundo caso, en el proceso (VTALB-FAC-FOR) hacemos uso de una cesta y un bucle for que recorre la cesta generando las sublistas que alimentarán el proceso de facturación. Con ayuda de los comandos Cesta: Procesar y Cortar lista, vamos generando las sucesivas sublistas. El comando Cortar lista no afecta al contenido de la cesta, por lo que podremos usarlo en cada vuelta del bucle para generar la siguiente sublista.
La variable local NumeroAlbaranes nos permite definir cuántos elementos compondrán la sublista. Este número podemos hacerlo configurable o bien podemos calcularlo en función del número de registros que contiene la lista, y si queremos también teniendo en cuenta el número de históricos, de lÃneas de albarán, de tal forma que optimicemos aún más el proceso. Incluso podemos preguntárselo al usuario antes de lanzar el proceso.
El proceso de facturación (VTALB-GEN-FAC) es el mismo para ambos y, como vemos, marca los albaranes ya facturados, por lo que en caso de interrupción del proceso basta buscar los pendientes para continuar, no habiendo perdido las operaciones ya realizadas.
Después de esto, seguramente nos preguntaréis cuál es el número ideal de operaciones por transacción. Pero no os podremos responder porque depende de varias cosas: la máquina en la que se ejecuten los procesos, tanto de procesador como de velocidad de escritura en disco, la carga de trabajo del servidor, lo complejo que sea el proceso que realicéis, etc. Teniendo en cuenta que un servidor normal puede realizar unas 4000 operaciones de alta y unas 10000 modificaciones por segundo, debemos hacer nuestra propia cuenta.
Etiquetas: c/s, cliente servidor, optimización, procesos, transacciones, Velneo, vserver










Diciembre 11, 2008 - 17:56 #
¡Estupendo! Valoro mucho que se den estas molestias para aclararnos puntos importantes a tener en cuenta en nuestros desarrollos, entregándonos ejemplos “casi” completos.
Muchisimas gracias.
Saludos.
RolandoCF