Está en la página 1de 7

Guas tcnicas Grupo Danysoft:

Aplicaciones de Bases de Datos con Delphi III

Equipo Grupo Danysoft julio de 2003 - (902) 123146 www.danysoft.com

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

Este documento se ha realizado utilizando Doc-To-Help , distribuido por :

Danysoft Internacional Avda de Espaa 17 28100 Alcobendas Madrid Tfno. 902.123146 Fax. 902.123145 http://www.danysoft.com http://www.danyshop.com danysoft@danysoft.com

www.danysoft.com - Pgina 2/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

Aplicaciones de bases de datos con Delphi


Una estrategia para su desarrollo (3ra. entrega) Otro punto fuerte de los componentes ClientDataSet y DataSetProvider es la reconciliacin de errores de actualizacin. Borland provee un mecanismo completo que nos permite indicarle al usuario con precisin l o los errores ocurridos al intentar aplicar sus modificaciones. Incluso podemos permitirle que realice las acciones que crea oportunas para intentar resolver el problema que gener el error y volver a aplicar las actualizaciones. El registro de cambios El ClientDataSet mantiene los cambios realizados por el usuario en memoria, ms concretamente en su propiedad Delta. Para cada registro modificado, el ClientDataSet almacena la siguiente informacin en el registro de cambios: Si el registro fue insertado, el registro insertado completo. Si el registro fue eliminado, el registro eliminado completo. Si el registro fue modificado, el registro original completo y el registro modificado pero solamente los campos que han sido modificados. La propiedad ChangeCount indica la cantidad de registros en el registro de cambios. Si el valor de ChangeCount es cero entonces lo s datos del ClientDataSet no han sido modificados. La propiedad UpdateStatus indica el estado del registro actual. Los posibles estados son: usInserted, usDeleted, usModified y usUnmodified. La propiedad StatusFilter nos permite filtrar los registros visibles dependiendo del valor de la propiedad UpdateStatus. Por defecto estn visibles los registros insertados, modificados y, por supuesto, los no modificados. Los datos originales son mantenidos en la propiedad Data. La estructura de los datos contenidos en la propiedad Data es igual a la estructura de los datos mantenidos en la propiedad Delta. Esto significa que podemos asignarle el valor de la propiedad Delta de un primer ClientDataSet a la propiedad Data de un segundo ClientDataSet y tener acceso, desde el segundo ClientDataSet, al registro de cambios del primer ClientDataSet. Errores de actualizacin Lo descrito en los prrafos anteriores es utilizado por el DataSetProvider para resolver las actualizaciones. El proceso de actualizacin comienza con una llamada al mtodo ApplyUpdates del ClientDataSet. Este mtodo recibe un parmetro que indica la cantidad mxima de errores de actualizacin tolerados antes de finalizar el proceso de actualizacin. El valor -1 indica que el proceso de actualizacin debe ser completado sin importar la cantidad de errores ocurridos. El valor 0 indica que el proceso de actualizacin debe ser finalizado ante el primer error. El valor 1 ante el segundo y as sucesivamente. El comportamiento del proceso de actualizacin depende entonces del parmetro que le pasamos al mtodo ApplyUpdates y de la cantidad de registros en el registro de cambios. La siguiente tabla muestra como se comporta el DataSetProvider en distintos escenarios. En dicha tabla puede verse claramente como la cantidad de registros actualizados depende no slo de la cantidad de errores de actualizacin ocurridos sino tambin del valor que le pasamos a ApplyUpdates. ApplyUpdates Cantidad de registros Error en registro N Registros actualizados

www.danysoft.com - Pgina 3/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

-1 0 1

3 3 3

1y3 2 2

1 (el 2) 1 (el 1) 2 (el 1 y el 3)

En la segunda entrega vimos la secuencia de eventos que genera el DataSetProvider durante el proceso de actualizacin. Cuando ocurre un error al intentar actualizar un registro el DataSetProvider genera el evento OnUpdateError, en el que recibimos informacin detallada acerca del error ocurrido, el registro que gener el error y el tipo de actualizacin que se intent realizar. En este evento podemos indicarle al DataSetProvider la accin que queremos que lleve a cabo con el registro en cuestin. Dependiendo del valor pasado a ApplyUpdates, el DataSetProvider continuar con el proceso de actualizacin o lo cancelar. Cuando ocurre un error de actualizacin el DataSetProvider finaliza la transaccin actual deshaciendo los cambios realizados, es decir, la finaliza haciendo Rollback. Debido a que las relaciones maestro/detalle son actualizadas en el contexto de la misma transaccin, si, por ejemplo, ocurre un error al actualizar un registro del detalle, los cambios al maestro sern cancelados. Sin embargo, si en el registro de cambios hay varios registros del maestro con sus correspondientes detalles, los registros actualizados correctamente no sern cancelados ya que fueron actualizados en el contexto de otra transaccin. Reconciliacin de errores de actualizacin Al finalizar el proceso de actualizacin, ya sea porque se comp let o porque finaliz debido a que se super la cantidad mxima de errores de actualizacin tolerados, el DataSetProvider le informa al ClientDataSet lo ocurrido. Para cada registro hay tres situaciones posibles: que el registro haya sido actualizado, que el registro no haya sido actualizado debido a un error de actualizacin o que el registro no haya sido actualizado porque el proceso de actualizacin finaliz antes de intentar actualizarlo. A continuacin se describe lo que ocurre en cada caso: Los registros que fueron actualizados son quitados del registro de cambios y mezclados con los registros originales. Para cada uno de los registros que no fueron actualizados debido a un error de actualizacin, el ClientDataSet genera el evento OnReconcileError. En este evento recibimos informacin detallada acerca del error ocurrido, el registro que gener el error y el tipo de actualizacin que se intent realizar. Aqu tambin podemos indicarle al ClientDataSet la accin que queremos que lleve a cabo con el registro en cuestin. Es importante escribir un manejador para este evento ya que de lo contrario corremos el riesgo de no enterarnos si han ocurrido errores de actualizacin. Esto se debe a que el ClientDataSet no genera excepciones por errores de actualizaci n. Los registros que no fueron actualizados porque el proceso de actualizacin finaliz antes de intentar actualizarlos, son mantenidos en el registro de cambios. Para estos registros no se genera ningn evento. El mtodo ApplyUpdates devuelve un valor entero que indica la cantidad de errores de actualizacin ocurridos. Por ejemplo, el valor 0 indica que no hubo errores de actualizacin. En lugar de escribir un manejador para el evento OnReconcileError podemos evaluar el valor devuelto por ApplyUpdates para saber si ocurrieron errores de actualizacin. Para reconciliar los errores de actualizacin Borland provee la unidad RecError, conteniendo la funcin HandleReconcileError, que le presenta al usuario un
www.danysoft.com - Pgina 4/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

formulario con informacin del error y la posibilidad de realizar acciones correctivas para intentar actualizar nuevamente el registro que gener el error.

La imagen de arriba muestra el formulario presentado por la funcin HandleReconcileError para el caso de un registro que no pudo ser actualizado debido a un problema de concurrencia. En este caso, el usuario intent modificar el campo OnOrder de la tabla Parts del alias DBDemos pero otro usuario modific el mismo registro asignndole otro valor a dicho campo. El ClientDataSet nos permite acceder al valor ingresado por el usuario (propiedad Value), el valor original obtenido por el usuario (propiedad OldValue) y el valor actual en la base de datos (propiedad CurrValue). El idioma original de este formulario es ingls pero el cdigo fuente est disponible en el directorio de la VCL por lo que podemos modificarlo para traducirlo, por ejemplo, al castellano. En todos los casos, los registros que no fueron actualizados permanecen en el registro de cambios tal y como los modific el usuario. Esto es muy importante ya que significa que el usuario no pierde las modificaciones realizadas y que puede realizar acciones correctivas para intentar solucionar el problema que gener el error de actualizacin. Por ejemplo, supongamos que el usuario ha ingresado una orden con 40 tems y la cantidad de stock disponible para el producto del ltimo tem no es suficiente para satisfacer el pedido. El usuario no slo no pierde todos los datos de la orden sino que podemos informarle la cantidad disponible para que modifique el tem nmero 40 para que la orden pueda ser procesada. Transacciones y actualizaciones encadenadas Los eventos del DataSetProvider nos permiten encadenar actualizaciones como si estuviramos utilizando disparadores en una base de datos SQL. Por ejemplo, en el evento BeforeUpdateRecord generado antes de actualizar cada tem de una orden, podemos escribir cdigo para actualizar el stock del producto. Este cdigo podra estar contenido en el Data Module de lgica de datos de productos y utilizar un

www.danysoft.com - Pgina 5/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

ClientDataSet y un DataSetProvider para acceder a un producto en particular. No sera necesario repetir este cdigo en el mencionado evento. Todo lo que tenemos que hacer es llamar al mtodo apropiado en el Data Module de lgica de datos de productos. En este Data Module, el DataSetProvider de productos, al momento de actualizar el stock de un producto, no iniciar una nueva transaccin porque detectar que ya existe una transaccin iniciada (el DataSetProvider de rdenes la inici) por lo que slo se limitar a actualizar la tabla de productos. Es ms, como el DataSetProvider de productos no inici la transaccin tampoco la finalizar. En este esquema es fundamental generar una excepcin si ocurre un error al actualizar la tabla de productos. De esta forma el DataSetProvider de rdenes, al capturar la excepcin, podr finalizar la transaccin actual cancelando los cambios realizados. Estas caractersticas del DataSetProvider nos permiten encapsular la lgica de productos en el Data Module de productos; la lgica de rdenes en el Data Module de rdenes y as sucesivamente. De esta forma la aplicacin ser ms fcil de modificar y tendremos ms posibilidades de reutilizar cdigo. Por ejemplo, si por algn motivo debemos modificar el proceso de actualizacin del stock de productos, slo tendremos que hacer cambios en el Data Module de lgica de datos de productos. Actualizaciones en cascada El DataSetProvider soporta el uso de actualizaciones en cascada para la eliminacin y modificacin de registros en relaciones maestro/detalle. Este soporte est pensado para aquellos casos en los cuales, por ejemplo, la eliminacin de una orden est completamente resuelta en la base de datos. Es decir, aquellos casos en los que slo tenemos que eliminar el registro maestro ya que en la base de datos, por medio de disparadores, los registros del detalle sern eliminados automticamente. En estos casos, el DataSetProvider slo deber generar sentencias SQL de DELETE para el registro maestro. Por medio de la propiedad Options del DataSetProvider podemos indicar si dicho DataSetProvider soporta eliminaciones y actualizaciones en cascada. En el ClientDataSet, cuando el DataSetProvider soporta eliminaciones en cascada, podemos eliminar un registro del maestro aun cuando existan registros en el detalle. Esto es as porque el DataSetProvider asume que la base de datos se encargar de eliminar los registros del detalle. Hay que tener mucho cuidado con las eliminaciones y actualizaciones en cascada ya que el DataSetProvider no generar sentencias SQL para eliminar o actualizar los registros del detalle y, por lo tanto, no generar los eventos BeforeUpdateRecord y AfterUpdateRecord para los registros del detalle. Si la lgica de datos de nuestra aplicacin utiliza estos eventos para los registros del detalle entonces no deberamos habilitar eliminaciones y actualizaciones en cascada. La nica limitacin ser que no podremos eliminar un registro del maestro si existen registros en el detalle. Esta limitacin puede ser fcilmente resuelta si antes de eliminar un registro del maestro eliminamos todos los registros del detalle. Conclusiones La reconciliacin de errores de actualizacin es un tema muy importante que pocas veces consideramos como es debido. Los errores de actualizacin pueden significar una experiencia frustrante para los usuarios de nuestra aplicacin. El esfuerzo dedicado a que este proceso sea lo ms amigable posible ser muy bienvenido por ellos y nos ahorrarn muchas llamadas de soporte.
www.danysoft.com - Pgina 6/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

El mecanismo ofrecido por Borland puede ser suficiente en la mayora de los casos, pero si necesitamos modificarlos tenemos todas las herramientas para hacerlo. El formulario contenido en la unidad RecError es una fuente de aprendizaje invalorable, como la mayor parte del cdigo fuente de la VCL. Analizando el cdigo fuente de esta unidad podemos aprender mucho y ajustar a nuestras necesidades el mecanismo ofrecido por Borland. Otro concepto fundamente es la encapsulacin. La gestin de transacciones del DataSetProvider nos permite anidar actualizaciones como si se tratara de disparadores. Esto nos da la posibilidad de encapsular la lgica de datos en distintos Data Modules y hacer que nuestras aplicaciones sean ms fciles de actualizar y mejorar las posibilidad de reutilizar cdigo.

www.danysoft.com - Pgina 7/7

También podría gustarte