Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Asesoramiento: ¿Tablas temporales, datos en memoria...? (https://www.clubdelphi.com/foros/showthread.php?t=34141)

kuan-yiu 28-07-2006 12:53:58

Asesoramiento: ¿Tablas temporales, datos en memoria...?
 
Hola a todos y gracias por el interés. He intentado simplificar los detalles e ir al grano, pero si hay dudas profundizo en el tema.

Tengo que revisar una aplicación que está dando problemas de grabación ya que se producen inconsistencias en la BD. Utilizo Delphi7 y Oracle9i.
Es un sistema para dar de alta solicitudes de clientes de forma telefónica, y se utilizan 3 formularios para los diferentes pasos, y ese es el problema, que cada formulario graba lo suyo sin llevar un control de coherencia y al final te puedes encontrar con líneas de presupuesto sin cabecera si se produce algún fallo durante el proceso o se cancela.

Consta de 3 tablas:
* Solicitud: cabecera que engloba una llamada concreta de un cliente que suele traducirse en varios presupuestos relacionados.
* Det_Solicitud: cabecera del presupuesto (para una única empresa).
* Det_Ppto: líneas del presupuesto, servicios concretos de la empresa.

Mi intención era crear 3 tablas temporales (o algo así) para almacenar los datos y sólo grabar al finalizar totalmente el proceso.

Me gustaría:

* Algo sencillo de incorporar, ya que tengo que revisar y sustituir un montón de código.

* Preferiría no tocar físicamente la BD ya que es una aplicación cliente/servidor que se mantiene por un sistema de espejos que se replican desde los servidores de las delegaciones al servidor central... un lío tremendo. Además no soy el administrador de la BD y hay que solicitar los cambios por escrito y los tiene que firmar el jefe de proyecto... otro lío.

* Nunca serán demasiados datos, lo normal son unos 10 registros relacionados contando las 3 tablas.

* Algunos de los datos son consultados durante el proceso y deberán ser accesibles mediante grid o edit. Estas consultas SQL ya existen y si se pudiesen mantener sería perfecto.

* Si es en memoria mejor, así se borra todo cuando cierre los formularios.



¿Qué debo utilizar? ¿Cual es el mejor modo de mantener y consultar la información hasta el momento de la grabación?

roman 28-07-2006 22:56:53

¿Qué para esto ne te sirven las transacciones? Si algo falla se cancela la transacción y con ello todos los cambios que se hayan hecho.

// Saludos

kuan-yiu 31-07-2006 09:30:50

Cita:

Empezado por roman
¿Qué para esto ne te sirven las transacciones? Si algo falla se cancela la transacción y con ello todos los cambios que se hayan hecho.

// Saludos

¿?
Estoy hablando de un proceso que puede tardar minutos en completarse, creo que eso va en contra del concepto de transacción... O por lo menos a mí no me acaba de convencer tener una transacción abierta durante tanto tiempo.

Héctor Randolph 31-07-2006 15:32:08

Hola kuan-yiu!

Con respecto al tema de no tener tanto tiempo abierta una transacción, leí hace poco una solución propuesta por Lepe en este hilo que se refiere a los ClientsDataset con cacheUpdates (consigues el efecto que una tabla temporal).

Te dejo un enlace con un ejemplo:


ClientDataSet y DataSetProvider en aplicaciones cliente/servidor


Saludos

kuan-yiu 31-07-2006 16:17:59

Cita:

Empezado por Héctor Randolph
Hola kuan-yiu!

Con respecto al tema de no tener tanto tiempo abierta una transacción, leí hace poco una solución propuesta por Lepe en este hilo que se refiere a los ClientsDataset con cacheUpdates (consigues el efecto que una tabla temporal).

Te dejo un enlace con un ejemplo:


ClientDataSet y DataSetProvider en aplicaciones cliente/servidor


Saludos

mmm... Cierto, cierto, no se me había ocurrido...
(Pero voy a tener que reescribir la mitad de la aplicación :( porque el que lo hizo ni usaba DataModule ni UpdateSQL ni nada de nada.)

roman 31-07-2006 18:04:11

Vamos a ver, que no soy experto en el tema así que más es pregunta que respuesta. ¿Exactamente, en este caso, cuál sería el problema de dejar una transacción abierta? No estamos hablando de dejar bloqueos de tablas activos. Dependiendo, según entiendo, del nivel de aislamiento de la transacción, los otros clientes pueden continuar su trabajo. Cualquier cosa que haya que deshacer con la transacción también ha de deshacerse con el uso de tablas temporales. No digo que no convenga usar ClientDataSets, y posiblemente sea lo más adecuado, pero tampoco me queda claro el porqué afecta una transacción abierta. Pero como dije, es más pregunta que respuesta.

// Saludos

kuan-yiu 31-07-2006 18:39:43

Cita:

Empezado por roman
Vamos a ver, que no soy experto en el tema así que más es pregunta que respuesta. ¿Exactamente, en este caso, cuál sería el problema de dejar una transacción abierta? No estamos hablando de dejar bloqueos de tablas activos. Dependiendo, según entiendo, del nivel de aislamiento de la transacción, los otros clientes pueden continuar su trabajo. Cualquier cosa que haya que deshacer con la transacción también ha de deshacerse con el uso de tablas temporales. No digo que no convenga usar ClientDataSets, y posiblemente sea lo más adecuado, pero tampoco me queda claro el porqué afecta una transacción abierta. Pero como dije, es más pregunta que respuesta.

// Saludos

Yo tampoco lo tengo muy claro, pero siempre me han insistido en que las transacciones tienen que durar el menor tiempo posible... Y yo me fío de quien me lo dijo.

El problema radica, creo yo, en un mal diseño inicial de la aplicación que ahora está dando muchos fallos y tengo que remendar de algún modo (usa 6 formularios diferentes durante todo el proceso, muchos de ellos de consulta y hay decenas de lugares en los que puede cancelar el proceso a media grabación produciendo los más variados desastres).
Así que lo que yo pretendo es unificar la grabación física en un único punto, al finalizar todo el proceso, para hacerla más robusta.Aunque tal vez esa tampoco sea la mejor solución. :confused:

kuan-yiu 31-07-2006 18:43:56

Cita:

Empezado por Héctor Randolph

Después de consultar durante gran parte de la mañana este ejemplo (que jaleo de relaciones) y de empezar a implementarlo me he encontrado con un gran escollo: ofrece un excelente sistema maestro-detalle, pero en mi caso es maesto-detalle-linea... Y no lo admite :( ... De todos modos voy a mirar a ver si aplicándolo parcialmente me sirve.

mamcx 31-07-2006 18:51:29

Quizas por problemas de atomicidad... mientras esta el proceso otros pueden modificar los datos de base, lo que implica que para proteger el proceso se deberia de aislar la transaccion.

Si el proceso es de mucho tiempo, las transacciones no necesariamente es lo mejor.

roman 31-07-2006 18:57:23

Entiendo esto, pero si el que otros usuarios hagan modificaciones durante la transacción es algo que pueda afectar en este caso, pues lo mismo sucedería con las tablas en memoria ¿no?

// Saludos

kuan-yiu 31-07-2006 19:10:57

El proceso dura mucho, demasiado, es el típico proceso:
Cita:

Vendedor: ¿Qué desea?
Cliente: Esto... no, mejor esto...
Vendedor: ¿Así?
Cliente: No, no, vuelva atrás para ver que es lo que llevo...

O sea que puede ser rapídisimo o durar casi una hora.
El problema fundamental es que tengo que insertar cosas y luego consultar esos mismos datos... me estoy volviendo loca :mad: , estoy a punto de tirarlo todo y volver a hacerlo.

Estoy tentada de llenarlo todo de flags y de montones de mensajes de aviso y de mega-funciones-de-borrado-en-masa...

kuan-yiu 31-07-2006 19:13:18

Cita:

Empezado por kuan-yiu
Después de consultar durante gran parte de la mañana este ejemplo (que jaleo de relaciones) y de empezar a implementarlo me he encontrado con un gran escollo: ofrece un excelente sistema maestro-detalle, pero en mi caso es maesto-detalle-linea... Y no lo admite :( ... De todos modos voy a mirar a ver si aplicándolo parcialmente me sirve.

Y de paso me quito la razón a mí misma: le he revisado mejor y sí que se pueden hacer estructuras apiladas de más de 2 niveles. Yo ya he llegado a 3 y parece que va funcionando... A ver si esto cuaja, sino por lo menos conoceré mejor varios componentes.

lucasarts_18 31-07-2006 20:39:20

Cita:

Empezado por kuan-yiu
Mi intención era crear 3 tablas temporales (o algo así) para almacenar los datos y sólo grabar al finalizar totalmente el proceso.

a ver veamos, 3 tablas temporales ?, acaso no deberías iniciar una transacción al momento de grabar dicha información, con el típico botón grabar ?

RollBack y Commit, simpre los uso y nunca me han dado problemas, ahora no sé porque se deben ir grabando los datos a medida que se vaya completando el proceso, nunca he visto este tipo de aplicación :confused:

kuan-yiu 01-08-2006 09:27:45

Cita:

Empezado por lucasarts_18
a ver veamos, 3 tablas temporales ?, acaso no deberías iniciar una transacción al momento de grabar dicha información, con el típico botón grabar ?

RollBack y Commit, simpre los uso y nunca me han dado problemas, ahora no sé porque se deben ir grabando los datos a medida que se vaya completando el proceso, nunca he visto este tipo de aplicación :confused:

Yo no he dicho que esté bien hecha, no lo está, en absoluto.
Pero como voy a empezar una transacción en un botón de un formulario, cambiar 7 veces de formulario para hacer otras cosas y acabarla en otro botón de otro formulario... Me parece demasiado pretender meterlo todo en la misma transacción.

A ver, que parece que no me explico nada bien:

Form1 : graba "Solicitud" y borra posibles líneas anteriores de "Det_Ppto". Además de otras cosas.
Form2: graba "Det_Ppto", añade datos a "Solicitud" y borra posibles líneas anteriores de "Det_Solicitud". Además de otras cosas.
Form3: graba "Det_Solicitud". Además de otras cosas.
Form4: usado por "Form1" para seleccionar el cliente.
Form5: usado por "Form1" para seleccionar la empresa.
Form6: usado por "Form2" y "Form3".
Form7: usado por "Form2".

El problema, creo yo, radica en que las tablas han tenido que ser ampliadas porque se necesitaba almacenar una serie de datos que inicialmente no habían sido considerados y creo que se hizo mal, por eso el proceso da tantas vueltas.

kuan-yiu 02-08-2006 10:32:12

¡¡Ya lo tengo!!

He creado esta estructura de componentes:
* 3 TQuery con la consulta a la tabla correspondiente. Con la propiedad "Cached Updates" a true.
* 3 TDataSource para relacionar las consultas y mostrar los datos.
* 3 TUpdateSQL para controlar la inserción, relacionados con las consultas a través de la propiedad "UpdateObject".

He sustituido todas las inserciones en la base de datos por métodos apend en los correspondientes TQuery. Las modificaciones y borrados igual, primero un locate y después lo que corresponda.

Al finalizar todo el proceso, junto con la última grabación lanzo un procedimiento que inserta todos los datos en una única transacción.

Me soluciona todos los problemas:
* He tardado en encontrar la solución (y he intentado varias que no han servido) pero el resultado es simple y elegante... o eso me parece.
* Si no finaliza el proceso no graba nada.
* Permite consultar los datos en cualquier momento del proceso.
* La estructura de componentes está en un DataModule y es accesible para todos los formularios en cualquier momento.
* No tengo que redefinir nada en la BD.
* Me sirven los formularios tal y como están. Los cambios son mínimos.
* Me ahorro un móntón de consultas y chequeos que ahora están en un único punto.

avmm2004 21-08-2006 20:25:35

Si utilizas oracle 9i deberias utilizar transacciones (Startransaction, commit, rollback) y ademas hay otro tema que deberias tener en cuenta. Existen savepoints (puntos de restauración) los cuales puedes definir varios (bastantes) de manera que al deshacer una transaccion podrías darle un rollback a un punto o dos o tres o....... anteriores con lo cual tu programa podía ir cerrando etapas y no mantener una transaccion abierta tanto tiempo como dices (recursos, bloqueos . . . . .). De todas formas puede ser que el fallo no venga de la transaccion, (tendrías el mismo problema con tablas temporales) sino del planteamiento de la pantalla de entrada de datos y del momento en que bloqueas tablas / recursos del sistema.


La franja horaria es GMT +2. Ahora son las 04:56:07.

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