Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-08-2003
rafadrover rafadrover is offline
Miembro
 
Registrado: jun 2003
Ubicación: Mallorca
Posts: 48
Poder: 0
rafadrover Va por buen camino
Transacciones + ventanas MDI

Tengo un pequeño problema y agradeceria unas sugerencias, el problema es el siguiente, las transacciones y las ventanas MDI, por ejemplo tengo una ventana MDI fichaCliente, como la base de datos es interbase, tengo una transaccion activa, el usuario modifica datos el la tabla cliente, ahora abren la ventana facturacion, tambien MDI, me hacen una factura y al final me hacen un commit, con este commit se han guardado los datos de factura y de cliente, pero si hacen un rollback, pierdo los datos de cliente. Solucion, hacer un commit cuando se habre la ventana factura, o bien cuando pierde el foco la ventana cliente.
Todo esto es porque no trobajo en cachedUpdates y cuando le pido al usuario aplicar cambios cliente S/N, hago un commit o rallback (Es un poco heavy), que me sugeris, que cambie a cachedupdates o sabeis algun sistema mejor.

Gracias a todos.
Responder Con Cita
  #2  
Antiguo 18-08-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Te explico como yo lo hago

Las ventanas MDI sólo las utilizo para la visualización de datos en un Grid y hacer busquedas y cosas por el estilo, pero cuando tengo que modificar o añadir un registro, muestro una ventana modal con DBEdits (o lo que sea) y, al aceptarla es cuando hago el Commit de la transaccion (o el Rollback si la cancelan)

En tu caso podria mirar de hacer un Commit al aceptar (post) un registro.

Son sólo ideas

Última edición por __cadetill fecha: 18-08-2003 a las 15:27:35.
Responder Con Cita
  #3  
Antiguo 18-08-2003
Avatar de Voutarks
Voutarks Voutarks is offline
Miembro
 
Registrado: jul 2003
Ubicación: Islas Canarias
Posts: 118
Poder: 21
Voutarks Va por buen camino
La solución está simplemente en utilizar transacciones distintas para cada proceso. En un mismo programa se puede uyilizar perfectamente varias transacciones.

Si nos damos cuenta ambas operaciones no son una sola, es decir, no están directamente relacionadas, por lo tanto, lógicamente son dos procesos distintos y dos transacciones distintas. No tiene sentido que sean una sola.
Responder Con Cita
  #4  
Antiguo 18-08-2003
Avatar de Voutarks
Voutarks Voutarks is offline
Miembro
 
Registrado: jul 2003
Ubicación: Islas Canarias
Posts: 118
Poder: 21
Voutarks Va por buen camino
Bueno, en el post anterior hablaba de la situación más logica. A ver cómo se hace eso con Delphi. Puse que era fácil utilizar varias transacciones porque ahora uso los componentes IbObjects y con ellos se pueden asignar varios objetos 'Transaction' a un solo 'Connection' y luego decir a cada grupo de sentencias SQL que transacción utilizan, con lo que ya está todo solucionado. No todo el muno usa estos componentes, asi que perdón por el lapsus.

Con los componentes estándar de Delphi: para utilizar varias transacciones podríamos crear dinámicamente componentes de acceso a datos y manejarlos así, sobre la marcha, aunque la programación de esto es algo complicada. Es decir, crear un 'Transaction', un 'Connection', un 'Query', etc para cada ventana que se abra con lo que sería como si el usuario ubiese ejecutado la aplicación otra vez. Una opción que nadie usaría sería tener varios juegos de componentes de acceso a datos, uno para cada ventana MDI que se pueda abrir... pero ya digo, ni lo pienses.

Bien eso era para utilizar varias transacciones, pero ahora te voy a decir lo que yo haría, en tu caso:
Supongo que se te pierden los datos del otro formulario porque utilizas controles enlazados a datos. Personalmente no me gusta utiliazr estos controles, únicamente algún que otro DbGrid, y de solo lectura, donde es necesario (aunque yo he llegado a utilizar un StringGrid que 'cargo' tras una consulta SQL). Lo perfecto para ti serían controles normales, los cuales 'cargas' de datos.

Por pasos: Al abrirse un formulario abres la transacción, haces una o varias consultas para traer los datos, cierras la transacción. Después de que el usuario ha insertado o modificado los datos en el formulario y le da a un botón de aceptar entonces abres la transación, mandas los datos con un INSERT o UPDATE y cierras la transacción inmediatamente.

Así no queda la transacción abierta en ningún momento y no hay ningún problema con que el usuario maneje varios formularios a un tiempo. Si tienes, por ejemplo, algún control DbLookupComboBox, pon un simple Combobox y con una pequeña instrucción SQL 'cargas' la lista desplegable con los datos que interesan. Luego, al enviar la sentencia de inserción o modicicaión, primero lo compruebas para enviar el valor correcto.

Como ves, todo esto lleva más programación, pero los resultados lo merecen.
Responder Con Cita
  #5  
Antiguo 18-08-2003
rafadrover rafadrover is offline
Miembro
 
Registrado: jun 2003
Ubicación: Mallorca
Posts: 48
Poder: 0
rafadrover Va por buen camino
El problema que le veo tener una transaccion por ventana de entrada de datos es el siguiente, supongamos que la tabla cliente esta asignada a una transaccion, y la tabla factura a otra, creo un cliente desde una ventana MDI hago un commit, luego voy a la ventana factura, busco el cliente y este no esta, tengo que cerrar y abrir la tabla clientePorFactura para que se me reflejen los cambios. Creo. De todas maneras no lo he probado en serio, quizas me lo tendria que replantear.
Gracias.

La solucion de mantener un Grid en modo solo lectura tambien es possible, pero no es tan elegante, creo yo, no se.
Responder Con Cita
  #6  
Antiguo 18-08-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

Cita:
Posteado originalmente por Voutarks
En un mismo programa se puede uyilizar perfectamente varias transacciones.
Si bien es completamente cierta la frase anterior, también lo es que con determinados mecanismos de acceso, p. ej. BDE, la forma de conseguirlo dista mucho de ser la mejor, ya que, en el caso concreto del BDE, cada sesión (conexión) está asociada a una (y solo una) transacción. Es decir, para tener n transacciones diferentes, hay que tener abiertas n sesiones (conexiones) diferentes. Evidentemente, con mecanismos de acceso como IBX, IBO, ..., sí se pueden tener varias transacciones bajo la misma conexión, pero el compañero que inició el hilo no especifica que mecanismo utiliza.

Saludos.
Responder Con Cita
  #7  
Antiguo 18-08-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

bueno, parece que mientras escribía mi mensaje anterior ya habéis comentado el asunto.

Saludos.
Responder Con Cita
  #8  
Antiguo 18-08-2003
Avatar de Voutarks
Voutarks Voutarks is offline
Miembro
 
Registrado: jul 2003
Ubicación: Islas Canarias
Posts: 118
Poder: 21
Voutarks Va por buen camino
Justo, por eso te dije la opción de los controles normales y todo lo demás. Así no tendrías ese problema.

De todas maneras es algo lioso como te he contado tener en el mismo formulario, junto con los controles descritos antes, un grid.
Responder Con Cita
  #9  
Antiguo 19-08-2003
rafadrover rafadrover is offline
Miembro
 
Registrado: jun 2003
Ubicación: Mallorca
Posts: 48
Poder: 0
rafadrover Va por buen camino
Voy a liar un poco mas la cosa:
Supongamos que tenemos una ficha MDI cliente, y otra ficha MDI reserva, en la de cliente se inicia un transaccion, y al final un commit. En la de reserva igual. Desde la ficha de reserva se puede abrir la ficha de cliente, en forma modal, por tanto, cuando se tiene activa transaccion de reserva, se inicia otra, la de cliente, si ambas tablas tienen asociadas la misma transaccion, cuando se cierra la ventana cliente, esta hace el commit, guardando todos los datos de reserva, luego volvemos a la ficha de reserva, si hacemos un commit, todo va bien, pero si el usuario quiere cancelar el trabajo y son transacciones distintas, todas las operaciones de reserva, se cancelan, pero las de cliente al ser una transaccion distinta se han guardado. Que hacemos en estos casos? Modificar dinamicamente la transaccion de la tabla cliente?
Responder Con Cita
  #10  
Antiguo 19-08-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

Cita:
Posteado originalmente por rafadrover Voy a liar un poco mas la cosa:
Supongamos que tenemos una ficha MDI cliente, y otra ficha MDI reserva, en la de cliente se inicia un transaccion, y al final un commit. En la de reserva igual.
Si he entendido bien, hay dos transacciones, una en cliente y otra en reserva.

Cita:
Posteado originalmente por rafadrover Desde la ficha de reserva se puede abrir la ficha de cliente, en forma modal, por tanto, cuando se tiene activa transaccion de reserva, se inicia otra, la de cliente, si ambas tablas tienen asociadas la misma transaccion,
Imposible. Si se inician dos transacciones, son dos transacciones. No hay forma de ligar una transacción a la otra. Además, una de las características de cualquier sistema transaccional es el aislamiento entre transacciones.

Cita:
Posteado originalmente por rafadrover cuando se cierra la ventana cliente, esta hace el commit, guardando todos los datos de reserva,
Entiendo que es guardar los datos de reserva sin hacer commit.

Cita:
Posteado originalmente por rafadrover luego volvemos a la ficha de reserva, si hacemos un commit,
Correcto, ahora hacemos el commit en reserva.

Cita:
Posteado originalmente por rafadrover todo va bien, pero si el usuario quiere cancelar el trabajo y son transacciones distintas,todas las operaciones de reserva, se cancelan, pero las de cliente al ser una transaccion distinta se han guardado.
Si se ha hecho el commit en ambas transacciones (cliente y reserva) no hay forma de volver atrás (no al menos directamente), ni en una ni en otra. Además, debido a lo que comentamos anteriormente del aislamiento entre transacciones, lo que haya ocurrido con la transacción en cliente no afecta a lo que vaya a ocurrir con la transacción reserva. Entiende "no afecta" desde el punto de vista del mecanismo de confirmación (commit) o rechazo (rollback) de los cambios, otra cosa es que un cambio en los datos de una transacción pueda hacer que el servidor no acepte los cambios de otra debido a restricciones de integridad.

Saludos.
Responder Con Cita
  #11  
Antiguo 19-08-2003
Avatar de Voutarks
Voutarks Voutarks is offline
Miembro
 
Registrado: jul 2003
Ubicación: Islas Canarias
Posts: 118
Poder: 21
Voutarks Va por buen camino
A ver si lo entiendo, tienes un primer formulario que se abre y desde este se puede abrir un segundo formulario.

Lo que quieres entonces es que si después de que el usuario ha aceptado los cambios en el segundo formulario, si le da al botón cancelar en el primer formulario se deshagan los cambios que hizo en ese segundo formulario. Y también quieres dejar la opción, como comentaste al principio de este hilo, de que si el usuario modifica datos en el primer formulario, luego abre el segundo y cancela los cambios en el segundo form. se mantenga lo que escribió en el primero ¿correcto?

Pues entonces efectivamente tienes que utilizar dos transacciones y no tienes que hacer el commit de la transacción del segundo formulario cuando se le da al botón aceptar de este formulario, sino:

En el segundo formulario:
-> En el botón cancelar, haces un rollback de la segunda transacción.
-> En el botón aceptar simplemente cierras el formulario, sin más.

En el primer formulario:
-> En el botón cancelar, primero miras si la segunda transacción está activa y si es así haces un rollback de la segunda. Después un rollback de la primera.
-> En el botón aceptar, primero miras si la segunda trans. está activa y si es así haces un commit de esta. Finalmente haces un commit de la primera.

Lo malo es que desde el primer formulario no se van a poder ver los cambios que se hacen con el segundo, si es que tienen que verse. Si es necesario que sea así entonces podrías utilizar sólo una transacción pero tendrías que guardar los valores del registro o registros que modifica el segundo en algún lado, como en una matriz y luego si el usuario cancela en el primer form coger los datos de ahí y deshacer el cambio con una instruccion UPDATE. Además tendrías que hacer lo que dije en un mensaje anterior, lo de cargar los controles y cerrar la transacción y todo eso.
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


La franja horaria es GMT +2. Ahora son las 07:37:45.


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