Club Delphi  
    Paypal   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 Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 04-04-2007
luisgutierrezb luisgutierrezb is offline
Miembro
 
Registrado: oct 2005
Ubicación: México
Posts: 925
Poder: 21
luisgutierrezb Va por buen camino
Pues al restar habitaciones puede ser que alguien haya reservado la 2 y otro la 3 casi al mismo tiempo y por la resta el programa crea que le ganaron la habitacion, quiero imaginarme que se usa una BD "decente" la cual te debe soportar triggers y ahi en un before insert o before update segun como se manejen las tablas, que revise la habitacion, ya que ahi se haria la cola de actualizaciones a la BD...
Responder Con Cita
  #2  
Antiguo 04-04-2007
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 23
gluglu Va por buen camino
Muchísimas gracias a todos por responder.

Deseo aclarar varios asuntos :

Antes de nada ... de momento utilizo Interbase 7.5

1. No estoy hablando de dos transacciones dentro del mismo programa para este caso. Estoy hablando de dos puestos de trabajo diferentes.

La aplicación que estoy haciendo ahora, lleva funcionando más de 15 años en Clipper. La estructura en Delphi, o más bien la funcionalidad, pretende ser más o menos parecida. Por lo que agradezco enormemente los consejos de como hacer una cosa u otra pero en esto caso ese apartado lo tengo cubierto. Gracias una vez más por vuestros amables consejos.

En mi caso particular, y en este momento más particular todavía, lo que estoy intentando hacer es asignar un número de habitación a una reserva ya creada. Esto lo permito en cualquier momento de la reserva, ya creada o en el momento de crearla, hasta el propio Check-In. Es decir, permito crear reservas sin pre-asignación de habitaciones concretas. Simplemente indicando el tipo y número de habitaciones.

Cuando un usuario cualquiera de la red solicita se le muestren las habitaciones disponibles, se busca en la base de datos y se abre un nuevo form con los números de habitaciones disponibles para un periodo de fechas concreto.

En ese mismo momento, cualquier otro usuario de la red puede estar intentando hacer la misma operación de asignación de habitaciones pero para otra reserva diferente (o puestos a ser extremos, incluso sobre la misma reserva ...), que se pudiera solapar en fechas (o incluso para las mismas fechas) con la reserva del otro usuario.

Dos usuarios diferentes tienen abiertos cada uno su form que le muestra las habitaciones disponibles para el periodo de fechas de la reserva que estan tratando.

Aquí aparece el problema. Si un usuario elige una habitación y el otro usuario pretende elegir la misma habtiación (para un periodo de fechas igual o solapado), al segundo se le tiene que indicar que otro usuario ha elegido ya previamente esa habitación para las fechas correspondientes.

Pero lo que además deseo es que si el primer usuario, al final del proceso de asignación de habitaciones, decide no confirmar el proceso, pueda hacer un 'Rollback' y liberar de nuevo esas habitaciones seleccionadas.

Es por ello que pretendía poder informar al segundo usuario de que la habitación ya ha sido elegida por otro usuario diferente, sin obligar al primero a tener que realizar un Commit.


2. Por supuesto no estoy hablando en ningún caso que una transacción se queda abierta tres días ni nada así. Cada reserva tiene su 'estado' de reserva propio, y puede estar confirmada, sin confirmar, check-in, check-out, o así hasta 11 estados diferentes. Cambiar el estado es una operación de modificación sobre una reserva como cualquier otra modificación de otro de los datos de la reserva.

Pero si estoy utilizando componentes Data-Aware para mostrar datos de la reserva en pantalla, o tengo un error de conceptos muy grande, o no sé como hacer eso sin tener una transacción abierta.

Por lo tanto, en mi caso, tengo una transacción abierta para cada reserva, al ser entre otras cosas una aplicación MDI. Esta transacción se mantiene activa mientras un usuario tiene 'abierta' una reserva en pantalla para consultas y/o modificaciones.

Es este el caso al que ha hecho mención Román. No estoy hablando de cambiar el estado de una reserva a 'confirmada'. Estoy refiriéndome a que un usuario creando una reserva 'confirme' (commit) o 'anule' (rollback) una reserva que se está creando en ese momento.


3. En otros hilos sobre temas diferentes en estos últimos días (en concreto un hilo sobre saldos bancarios) se ha hablado de si es bueno mantener una tabla con 'saldos' (en unos casos bancarios) que en mi caso particular serían de habitaciones disponibles.

Decidí hace más de 15 años que al menos para mi, no era 'bueno' mantener esa tabla. La razón principal en su momento fue por la 'inestabilidad' de ese tipo de tablas en Clipper.

Estamos de acuerdo que hoy en día las bases de datos permiten mucha mayor estabilidad.

Pero sigo teniendo decidido que no voy a mantener esa tabla de habitaciones disponibles, porque entre otras cosas no sólo permito reservas habitaciones por días, sino también cualquier otro 'objeto' por horas, por minutos, o por intervalos. Además de poder reservas incluso 'camas' particulares de una habitación con varias camas (en el caso de hoteles p.ej. Bed & Breakfast, donde sea posible solicitar una cama en vez de habitaciones).

(Ay !! que tiempos aquellos en los que uno iba solito a Londres por ejemplo y dormía en una cama de una habitación compartida por otras 5 personas más que no conocías de nada !!) (Habría que denominar a eso hoy 'Low Cost Beds' ??!! )

Sigamos con el tema. Es por ello que si tengo un proceso de revisión de disponibilidad después de 'confirmar' la creación de una reserva. Tal y como también comenta Román. Pero sin tabla de habitaciones disponibles.

Y por supuesto que debe ser posible que se permitan y se den situaciones de overbooking, al menos desde el punto de vista informático a nivel de programación. Otra cosa muy diferente es establecer esas reglas o no de overbooking a nivel de usuario.

Pero a nivel informático (puro y duro desde el punto de vista de registros y base de datos), al menos como comento ahora, debe ser posible que dos usuarios diferentes estén realizando una reserva por un periodo de fechas igual o solapado que finalmente provoque una situación de overbooking, que será avisada de manera correspondiente y coherente cuando la situación lo requiera.


Espero no haberme 'enrollado' demasiado. Muchas gracias de nuevo a todos por vuestros comentarios.
__________________
Piensa siempre en positivo !

Última edición por gluglu fecha: 04-04-2007 a las 11:45:24.
Responder Con Cita
  #3  
Antiguo 04-04-2007
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 23
gluglu Va por buen camino
Añado ...

Gracias ArdiIIa. Ya conocía el documento de transacciones de nuestro compañero Kinobi. Lo he leido en varias ocasiones. Pero como siempre pasa en estos casos, uno siempre aprende algo nuevo al volver a leer de nuevo un documento que hayas podido leer previamente en varias ocasiones.

Y he localizado lo siguiente ...
Cita:

READ COMMITED NO RECORD_VERSION
: La transacción tiene acceso
a los registros modificados por otras transacciones que se estén ejecutando
concurrentemente. Si los cambios aún no han sido confirmados (
commit),
y la transacción tiene el parámetro
WAIT para la resolución de bloqueos,
esperará hasta que se confirmen (
commit) o rechacen (rollback). Si
por el contrario tiene el parámetro
NO WAIT, devolverá inmediatamente un
error a la aplicación cliente. En cualquier caso, una transacción nunca puede
tener acceso
real a registros modificados, pero no confirmados (commit);
InterBase
no soporta el llamado nivel de asilamiento READ UNCOMMITED,
también conocido como DIRTY READ.

Añado una nueva pregunta al hilo ... Firebird 2.0 soporta este tipo de 'Dirty Read' ??
__________________
Piensa siempre en positivo !
Responder Con Cita
  #4  
Antiguo 04-04-2007
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 23
gluglu Va por buen camino
Me contesto a mi mismo ...

He consultado la documentación de Firebird en esta página y he encontrado esto :
Cita:
Read locks - dirty reads Because records are tagged with their version and every transaction knows what transactions are currently active, no transaction can read a record version created by an active transaction. Dirty reads are impossible.
__________________
Piensa siempre en positivo !
Responder Con Cita
  #5  
Antiguo 07-04-2007
d-hugo d-hugo is offline
Miembro
 
Registrado: abr 2007
Posts: 34
Poder: 0
d-hugo Va por buen camino
gluglu,

A menos que no te haya entendido, me parece que tu problema radica en que estás intentando abarcar demasiado con una transacción. Esto no es necesario ni recomendable. Las transacciones se idearon para conseguir que las operaciones sobre las bases de datos tuvieran las cuatro propiedades denominadas ACID (Atomicity, Consistency, Isolation, and Durability).

Mi sugerencia (y puede no ser la mejor) es que informáticamente subdividas la operación: usa consultas y ClientDatasets para la introducción y modificación de datos en el formulario, y sólo en el momento preciso en que se vaya a escribir a la base de datos se inicia la transacción, se pasan los datos pertinentes de los ClientDatasets o controles a las tablas que corresponda y se hace el COMMIT, o ROLLBACK en caso de algún error. De esta manera la transacción tomará como máximo un par de segundos y de haber alguna condición que no permita hacer el commit, el usuario no tendrá que recomenzar desde cero. Verificar si la habitación ha sido asignada se resuelve con un simple SELECT. Para más seguridad, se puede volver a lanzar ese SELECT dentro de la transacción justo antes de asignar definitivamente la habitación, e incluso si se desea se puede programar un timer que ejecute regularmente dicha consulta durante todo el tiempo que el usuario tenga abierto el formulario (claro, que esto implicaría más tráfico en la red).
La idea es usar las transacciones solo para las instrucciones que modifiquen la base de datos, como INSERT, UPDATE o DELETE. El resto de las cosas generalmente se puede resolver con consultas. Si es necesario actualizar muchos datos en cascada se pueden crear triggers. De lo contrario uno puede terminar con un montón de transacciones abiertas simultáneamente durante un largo rato, lo cual puede ser fuente de interminables frustraciones por problemas de concurrencia. Así que mejor evitarte todo esto desde ahora que estás diseñando el nuevo sistema (es el momento ideal).

Espero haberte sido de alguna ayuda.

Saludos, Hugo.
Responder Con Cita
  #6  
Antiguo 04-04-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 24
Mick Va por buen camino
Cita:
Empezado por luisgutierrezb
Pues al restar habitaciones puede ser que alguien haya reservado la 2 y otro la 3 casi al mismo tiempo y por la resta el programa crea que le ganaron la habitacion, quiero imaginarme que se usa una BD "decente" la cual te debe soportar triggers y ahi en un before insert o before update segun como se manejen las tablas, que revise la habitacion, ya que ahi se haria la cola de actualizaciones a la BD...
El tema que comentas no tiene mayor problema, esto se puede detectar mas o menos de forma facil de varias formas, ejemplo sencillo, tenemos una tabla llamadas HABITACIONES con un unico registro y un campo llamado CANTIDAD:

-Iniciar una transaccion
-Digamos que queremos reservar 2 habitaciones:
UPDATE HABITACIONES SET CANTIDAD=CANTIDAD-2 WHERE CANTIDAD>2
-Comprobamos el numero de registros que ha modificado el update, y si es igual a 0, no tenemos habitaciones libres suficientes y cancelamos la transaccion.

Esto se puede aplicar igualmente al problema de gluglu, todo consiste en hacer el update con una condicion WHERE adecuada que no
se cumplira si otro usuario ha realizado un update sobre el mismo registro antes, o si no se cumplen los requisitos (en este caso que haya menos habitaciones
de las que queremos restar). Ni siquiera se necesitan usar transacciones si el proceso de reserva implica modificar un solo registro, solo harian falta
transacciones en el caso de que haya que modifica mas de un registro.

Última edición por Mick fecha: 04-04-2007 a las 14:01:42.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Transacciones juanmdq Oracle 3 12-01-2007 14:59:42
transacciones Investigador Conexión con bases de datos 2 08-12-2006 01:02:08
Limitar número de usuarios concurrentes mlara Firebird e Interbase 0 25-11-2006 21:13:38
conexiones concurrentes?? andresenlared Conexión con bases de datos 1 02-08-2006 02:31:30
Control de usuarios concurrentes Toni Providers 2 02-08-2004 15:43:17


La franja horaria es GMT +2. Ahora son las 01:27:43.


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