Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-09-2012
rolandoj rolandoj is offline
Miembro
 
Registrado: abr 2007
Posts: 395
Poder: 18
rolandoj Va por buen camino
Transacciones en Zeos. Conviene una por Conexión ?

Hola a todos,

Investigando sobre Zeos me encontré con un tema que me sorprende. Es una pregunta para veteranos de Zeos; pero, como es igualmente clave para principiantes explicaré en detalle el concepto antes de preguntar:

Parte vital del trabajo normal que uno hace al grabar datos en una Base de Datos es la inserción, borrado y modificación de registros.

Por ejemplo, y típicamente, un documento está formado por un registro en una tabla maestra y múltiples registros hijos en varias tablas detalle. Por integridad de la información, bajo el principio de "todo se graba o no se graba nada", todos los registros de las diversas tablas involucradas se guardan bajo una sola transacción.

Eso, también usualmente, se hace entre dos puntos de código de nuestro programa con un comando Startransaction y un comando Commit, que suministra el componente de conexión a la base de datos. En el caso de Zeos ese componente es TZConnection.

Por tanto, la secuencia de trabajo con un componente TZConnection (u equivalente) debería ser :

Configurar los parámetros de conexión
Abrir la conexión (propiedad Connected a True)

Por cada ocasión en que se deba grabar un bloque de registros :

Invocar el método StartTransaction
Efectuar las operaciones de inserción, borrado y modificación de registros.
Invocar el método Commit
Si hay errores, invocar el método Rollback para restaurar todo al estado inicial

Finalmente, cerrar la Conexión (propiedad Connected a True)

Ahora viene la pregunta :

Según lo que leí, el método Commit en Zeos usa un "commit suave"; eso significa que los recursos que utilizó en el transcurso de la transacción, típicamente copias temporales de registros involucrados, no son liberados (al menos para el caso de Firebird que era el ejemplo que ilustraban). Esto implica que en tablas grandes, pasado algún tiempo, el rendimiento de la base de datos se degrada.

Para que los recursos temporales usados en una transacción se liberen, en Zeos, se requiere emitir un "commit duro", y ese comando solo lo emite en Zeos cuando se cierra la conexión

La conclusión que saco es que, para efectos de mantener un buen rendimiento, la metodología en Zeos sería que una vez abierta la conexión se iniciara una transacción y una vez terminada esta se cerrara la conexión; es decir, usar una sola transacción por conexión

Sin embargo, eso va en contravía del modelo tradicional de mantener abierta la conexión mientras se efectuan multiples transacciones. El modelo tradicional parte de que al abrir la conexión se colocan en cache una serie de recursos que posteriormente permite mayor velocidad en las operaciones.

Así las cosas, la gran pregunta es : Conviene en Zeos manejar solo una transacción por conexión, sacrificando el cache de inicio de conexión; o es mejor mantener el modelo tradicional, sacrificando el rendimiento directamente sobre la Base de Datos.

Ciertamente no es una pregunta facil. Será que alguien ha participado en discusiones de este tema ?. Alguien sabe de estadísticas a favor o en contra de eso ?.

Bueno, alguien puede confirmar la interpretación que hago al final ?. Es una traducción de un material escrito de manera algo vaga en Inglés y quizás estoy malinterpretando algo

Última edición por rolandoj fecha: 27-09-2012 a las 16:10:14. Razón: El foro no respetó los saltos de línea en el envío inicial
Responder Con Cita
  #2  
Antiguo 27-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sí se ha hablado antes sobre este tema, a saber dónde.
En mi caso, y en el caso de otros muchos, tenemos sólamente un componente database y otro transaction. Así que todas las acciones con la base de datos pasan por un único componente transaction. No recuerdo cómo es con Zeos, pero con las IBX (por poner un ejemplo) son los componentes TIBdatabase y TIBtransaction. Todos los componentes dataset añadidos: query, tablas, etc. se enlazan con ese tibdatabase y el tibdatabase está enlazado con ese tibtransaction.
Lo que dices de "commit suave" es un "commitretaining".
Si has usado un cajero automático de los bancos, verás que si haces 2 transacciones seguidas, por ejemplo (te pregunta si vas a hacer otra transacción y le contestas que 'sí'), sacar 20 euros y después sacar otros 20 euros, verás que el sistema vuelve a empezar, saca la tarjeta de crédito/débito y la vuelve a insertar para iniciar la segunda transacción, o sea, que cierra por completo la transacción e inicia otra, no deja nada "a medias", eso es lo más seguro.
Pero como bien dices, en una gestión comercial, por ejemplo, es un método "laborioso" trabajar de esa forma. Por lo que normalmente no se hace en todas las ocasiones.
Lo que dices de firebird no es ningún problema, firebird trabaja con "versiones" de registros, no representa inconveniente alguno, es simplemente una forma de controlar las transacciones. Esos "registros inservibles" se limpian automáticamente, aunque también lo puedes hacer manualmente, basta realizar un backup/restore para que se desechen.
En mi caso, siempre instalamos un sistema de backup en los servidores firebird, para que se ejecuten por la noche, y dejan la BD limpia y reluciente para iniciar el siguiente día , son BD de muchos gigas y bastantes conexiones simultáneas, habitualmente, por lo que en un sólo día aumentan varios gigas.
Se hace el backup por seguridad, no porque ralentize el sistema.
El otro día un usuario (de clubdelphi) decía que tenía una BD de 10 gigas y que era algo lenta, le aconsejé hacer un backup/restore y volvió a la normalidad, además de ocupar menos de 400 megas, parece que nunca jamás había hecho "limpieza" de la BD
Te aconsejo que leas "EL" documento por excelencia sobre transacciones.
Responder Con Cita
  #3  
Antiguo 27-09-2012
rolandoj rolandoj is offline
Miembro
 
Registrado: abr 2007
Posts: 395
Poder: 18
rolandoj Va por buen camino
Limpian automático ?

Hola Casimiro,

Veo que no estás muy seguro de como es usando Zeos; o sea, la limpieza es automática al hacer el commit ?. Según lo que yo había leído, el problema es que no se hace automáticamente hasta que se cierre la conexión.

En un entorno de servidor web, la conexión está permanentemente vigente hasta que se baje la librería. Según el tipo de aplicación, puede pasar mucho tiempo, incluso semanas, antes de eso, y el volumén de transacciones puede ser muy alto afectando el rendimiento.

Por otro lado, lo que dices de que es laborioso trabajar con Trabsacciones, es cierto en la medida de que el programador no haya establecido una buena metodología o herramientas de apoyo. En mi caso, eso es tema superado y siempre trabajamos, facilmente, con transacciones.

Y más allá de si se usa o no, el punto fuerte del tema es que se debería usar. Los programas que no lo hacen no están dando garantías razonables de integridad y consistencia en sus datos.

Por otro lado, buen dato lo del documento. Saqué algo de tiempo para leer un poco. Hasta donde voy son todas cosas que conozco desde hace años; pero, es largo, a lo mejor aparece algún dato nuevo para mi.
Responder Con Cita
  #4  
Antiguo 27-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Creo que no me he explicado bien
Zeos lo conozco de hacer pruebas y poco más, lo que no entiendo es qué quieres decir con lo de "¿la limpieza es automática al hacer el commit?", no sé a qué limpieza haces referencia.

En cuanto a las conexiones abiertas por la web, que yo sepa, son configurables para que se desconecten pasado un tiempo determinado, por el propio servidor web.

Y en cuanto a lo que dices sobre "la laboriosidad en el tratamiento de las transacciones", no me refería a eso, me refería a que en una gestión comercial no puedes estar desconectando a los usuarios y volviendo a conectarlos cada vez que hagan una transacción de cualquier tipo, salvo que uses un esquema similar a un cajero bancario. O sea, que tienes que usar commitretaining en lugar de commit.

A ver si ahora me he explicado mejor
Responder Con Cita
  #5  
Antiguo 27-09-2012
rolandoj rolandoj is offline
Miembro
 
Registrado: abr 2007
Posts: 395
Poder: 18
rolandoj Va por buen camino
Comentarios

Hola Casimiro,

Cuando hablaba de limpieza automática me refería sobretodo a los registros inservibles que tuvieron vida durante la transacción. Según lo que leí, al usar el método Commit de Zeos ellos no se limpian automáticamente. Para que se de la operación de limpieza hay que cerrar la conexión.

Ciertamente, el modelo Web, basado en librerías (otra cosa serían los ejecutables CGI), parte de que esas librerías permanecen en memoria, a fin de optimizar el acceso a las mismas.

Cuando pasado algún tiempo, configurable en el sistema, esas librerías, que están en memoria, no han recibido nuevas peticiones, el servidor Web las descarga de la memoria, operación que, lógicamente, cierra la conexión a la Base de Datos.

En el entorno más común, eso significa que en la práctica hay al menos una descarga de memoria al día. Sin embargo, en empresas que tengan producción de 24 horas, y/o operaciones con países de un uso horario distinto, es posible, dependiendo de la frecuencia de las operaciones, que pasen días o incluso semanas, sin que se descarguen las librerías. Son entornos en los que se hace necesario un frecuente manteniemiento programado.

Si las susodichas empresas tiene altos volumenes de operación, es claro que el rendimiento se degradaría más rápido.

De ahí mi pregunta, porque el tema sería de estadísticas : Hay estudios que confronten esa penalidad vs la penalidad de estar abriendo y cerrando la conexión por cada transacción.

Ten en cuenta que el modelo Web, que yo manejo, no opera como trabaja la mayoría de la gente. Todo el control transaccional existe solo en el servidor. El cliente no sabe nada de la base de datos y menos de transacciones.

Cada petición del cliente al servidor, si contiene alguna adición, modificación o borrado de datos. se hace en una sola transacción. Por lo anterior, en mi caso, adoptar el esquema de una conexión por transacción es programáticamente trivial, algo de minutos.

La razón es que solo tendría que modificar la macrorutina que responde a cada petición para abrir la conexión a la base de datos, hacer las tareas que hacía antes y cerrar la conexión al terminar.

En otras palabras, reubicar la apertura de la conexión, que actualmente hago a la carga de la librería, y el cerrado (actualmente en el descargue de la librería), para ponerlos en la macrorutina.

El problema pués no es de dificultad de programación sino de rendimientos. Hay que ver si se consigue mayor información
Responder Con Cita
  #6  
Antiguo 27-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por rolandoj
Cuando hablaba de limpieza automática me refería sobretodo a los registros inservibles que tuvieron vida durante la transacción. Según lo que leí, al usar el método Commit de Zeos ellos no se limpian automáticamente. Para que se de la operación de limpieza hay que cerrar la conexión.
Ni zeos, ni ibx, ni fibplus, ni ninguno... es que no tiene nada que ver con los componentes que estés usando. Tampoco tiene que ver con que hagas commit, commitretaining, rollback, etc. Firebird tiene una Arquitectura Multi Generacional, guarda "distintas versiones" de un mismo registro, lee esto:

Cita:
El control de concurrencia
Considere la posibilidad de una simple aplicación bancaria en la que dos usuarios tienen acceso a los fondos en una cuenta particular. Bob lee la cuenta y encuentra que hay 1.000 dólares en ella, por lo que retira 500. Jane utiliza la misma cuenta pero antes de que Bob haya aplicado los cambios, considera que hay 1000 dólares y retira 800. La cuenta debería tener 300 dólares en descubierto, sin embargo (asumiendo que no puede haber descubierto) dependiendo de la transacción que se procese primero, tendrá 500 ó 200 dólares. Esto plantea un grave problema ante el cual cualquier sistema de bases de datos con acceso multiusuario debe responder ofreciendo un sistema con el que gestionar estas situaciones.
Las técnicas utilizadas para resolver este y otros problemas relacionados, son conocidos como control de concurrencia .
Los productos tradicionales utilizan bloqueos cuando una determinada transacción va a modificar un registro. Una vez que el bloqueo se aplica, nadie más puede leer o modificar los datos hasta que éste se levante. El bloqueo se puede aplicar sobre un único registro, una página (un grupo de registros almacenados juntos en el disco) de registros o todos los registros examinados por una transacción en particular, dependiendo de la resolución de bloqueo. El bloqueo de resolución es una solución de compromiso entre rendimiento y precisión mediante la aplicación de bloqueo de actualizaciones a nivel de página. Algunos registros serán bloqueados a pesar de no entrar en conflicto con aquellos que sí van a ser actualizados por transacciones, sin embargo el rendimiento es mayor en comparación con el bloqueo a nivel de registro.
El bloqueo se convierte en un problema aún mayor cuando se combina con otra característica común a todos estos sistemas, el aislamiento. Esto se debe a que generalmente están relacionadas con las operaciones de lectura y una escritura. En este ejemplo, para leer el valor de la cuenta y luego cambiarla. Con el fin de mostrar una visión aislada de los datos de toda la transacción, incluyendo los registros que se van a leer pero no a escribir, debe ser bloqueado en los servidores de base de datos de muchos.
En Firebird, los lectores no ven el del escritor. Por ejemplo, cuando Bob y Jane leen los datos a ambos se les mostrará "versión 1", la lectura de 1.000 dólares. Cuando Bob haga cambios en la cuenta al hacer su retiro, los datos no se sobrescriben sino que una nueva "versión 2", esta vez con 500 dólares aparecerá. El intento de Jane de retirar 800 dólares fallará al encontrar que hay una nueva versión.
A este enfoque del control de concurrencia se le llama control de concurrencia multiversión. La aplicación Firebird de control de concurrencia multiversión comúnmente llama a su arquitectura multi-generacional. Firebird fue la segunda base de datos comercial en utilizar esta técnica, la primera fue diciembre 's Rdb / ELN.
El control de concurrencia multiversión también hace el aislamiento instantáneo de transacciones relativamente fácil de implementar. Una transacción con aislamiento instantáneo en Firebird muestra el estado de la base de datos precisamente en el instante en que la operación comenzó. Esto es muy útil para copias de seguridad de una base de datos activa , procesos de larga duración por lotes, etc.
Esos registros 'inservibles' no se borran, están ahí marcados como inservibles, su espacio será ocupado por cualquier otro. Sólamente con un backup/restore se eliminarán. También creo recordar que hay un parámetro en el comando gbak para eliminarlos. Pero no debes preocuparte por ellos, yo nunca he conocido ningún problema en ningún cliente, y es normal bases de datos entre 10 y 50 gigas, sin problemas, incluso algunos compañeros han comentado algo de clientes suyos con bases de datos mucho mayores.
Quiero decir con esto que no es un motivo de preocupación, que es sólo una característica, una forma de trabajar de firebird.


En relación al resto de tu comentario, puede que en tu caso te interese hacer commit cada vez, al igual que los cajeros bancarios.
Pero lo que yo te comentaba no era eso, sino el tener un sólo componente TIBTransaction (o como se llame) para todas esas transacciones, que no es necesario tener varios componentes de transacción, que uno sólo se encarga de todo.
Ahora bien, si te quedas más tranquilo poniendo más, pues nada, tampoco hay problema.

Y en cuanto al rendimiento, pues ya sabes, primero hay que hacer pruebas lo más realistas posible, antes de entregar nada al cliente.

Mira la entrada de Interbase en la wikipedia, lo dicho allí vale para Firebird.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problema con transacciones, sqlite y componentes ZEOS zoide Conexión con bases de datos 10 16-11-2009 13:10:05
transacciones y ZEOS david_uh Varios 0 26-05-2007 19:44:03
Transacciones - Que Conviene mas? Paradiso Firebird e Interbase 2 19-07-2006 14:35:21
Transacciones FireBird con Zeos vichovi Conexión con bases de datos 3 13-07-2005 08:49:29
Como Realizar transacciones con Zeos o en Delphi Dayvis MySQL 1 22-10-2004 03:00:47


La franja horaria es GMT +2. Ahora son las 20:14:56.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi