Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-07-2004
Halfo Halfo is offline
Registrado
 
Registrado: jul 2004
Posts: 9
Poder: 0
Halfo Va por buen camino
Talking Bloqueos tan superOptimistas que no me bloquean :(

Para situar un poco comentaré el entorno de trabajo:
BD: Firebird 1.5
Conectividad: IBX 6.01
RAD: Builder C++ 6
TIBTransaction = commit read_committed, rec_version, nowait

Ahora explicaré un poco más el problema:
Si no he entendido mal la filosofia de los "bloqueos" superoptimistas, más que un bloqueo es un conflicto normalmente a la hora de escribir en registros, no? O sea que si una transacción realiza una escritura en un campo de un registro y hace commit y una segunda transacción prueba a hacer lo mismo en el mismo campo del mismo registro deberia fallar y saltar el bloqueo optimista, no?
Yo entiendo que el ModifySQL de la segunda transacción si contiene en el WHERE todos los campos posibles de modificación no podrá actualizar por no encontrar registro alguno para modificar. Esto me parece quedar claro en este fragmento de la cara oculta:
Por supuesto, si alguien cambia cualquier dato del empleado 666, digamos que la extensión telefónica, la instrucción anterior no encontrará registro alguno y se producirá un fallo de bloqueo optimista.

Bueno, pues el problema es que no me salta ningun tipo de fallo de bloqueo ni nada. Yo pensaba que me saltaria alguna excepción como en el caso en que intentas repetir la clave primaria que si que falla el commit saltando una excepción. Pues no se si me esta fallando algo en la practica o no he entendido bien la teoria de los bloqueos optimistas.

En el caso del delete me pasa lo mismo me deja borrar un registro que ya habia sido borrado, aunque esto no es tan grave .
Pero vaya que me gustaria saber como funciona realmente el bloqueo optimista y poderlo usar, anque tambien he leido en el foro el 'simulacro' de bloqueo pesimista con un update inutil y tal pero me parece que tampoco solucionaria nada ya que la segunda transacción actua escribe o borra cuando la primera ya ha termindo (commit).

No se, alguien sabe como funciona todo esto realmente????

Gracias de antemano.
Responder Con Cita
  #2  
Antiguo 29-07-2004
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 22
Mick Va por buen camino
Tal como lo has explicado , no debe saltar ningun tipo de error.
Si la primera transaccion finaliza (con un commit o un rollback) ANTES de que la segunda transaccion haga la modificacion al mismo registro, no debe saltar ningun tipo de error.
Esto es debido a que la primera transaccion ha finalizado, de modo que el registro que se haya modificado ya ha quedado desbloqueado, de modo que cualquier otra transaccion puede modificar el registro sin problema alguno.
Se produciria un error si la primera transaccion estuviese sin finalizar cuando la segunda intentase modificar el mismo registro.

Si funcionase como explicas no serviria para mucho el sistema, ya que en cuanto cualquier transaccion tocase algun registro y finalizase, ese registro daria siempre error al intentar ser modificado posteriormente, lo que no tendria de mucha utilidad, no serviria para nada una base de datos que solo permitiese modificar los registros una sola vez y despues diesen siempre error.

Saludos
Responder Con Cita
  #3  
Antiguo 30-07-2004
Halfo Halfo is offline
Registrado
 
Registrado: jul 2004
Posts: 9
Poder: 0
Halfo Va por buen camino
A ver si me explico mejor:
Parte de lo que dice, Mick, lo entiendo perdectamente ya que si la segunda transacción no bloquea de forma pesimista con un lock, select for update o update inutil el registro,es normal que la primera transacción puede acceder al registro, modificarlo, comiterarlo y no encontrar problema alguno, luego la segunda transacción cuando quiera modificar (update) el mismo registro ya no actuará concurrentemente con la primera transacción que ya terminó.

Peró insisto que en este punto hay un problema. Según lo que creo haber entendido en "la cara oculta de C++" del señor Marteens, la modificación del registro realizada por la segunda transacción, si se realiza utilizando en la clausula WHERE todos los campos posibles de modificar (no solo la clave primaria, aunque en algunos casos esta tambien pueda cambiarse) resulta que la ejecución de la sentencia ModifySQL intenta un update sobre un registro que no encuentra, por lo que no puede realizar tal modificación, ahí es donde esta la anomalia.
Lanzando dicha sentencia SQL (update ....where ...) desde una utilidad SQL aparte se puede comprobar que la sentencia no afecta a ningun registro y devuelve:

This command did not return data, and it did not return any rows

mientras que si existiera el registro se obtendría:

1 Row(s) affected

YO ME PREGUNTO, ¿no es importante saber si realmente has podido realizar el update o no? los componentes IBX no informan de ninguna forma que la sentencia ha fallado, es decir no ha afectado a ninguna fila???

¿Me estoy equibocando en algo?¿la situación que planteo no es lo más normal si no se usan bloqueos pesimistas? de hecho el bloqueo optimista no se basa en esto: que todo el mundo pueda ir modificandolo todo hasta que salte un problema de este tipo?

Otra vez, gracias por la atención.
Responder Con Cita
  #4  
Antiguo 30-07-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Cool

Cita:
Empezado por Halfo
Peró insisto que en este punto hay un problema. Según lo que creo haber entendido en "la cara oculta de C++" del señor Marteens
...
los componentes IBX
El libro "La cara oculta de C++", al menos el que yo leí... hacia referencia a los componentes de acceso via BDE, y no a IBX, por lo que la referencia no necesariamente es válida.

De hecho, el comportamiento puede cambiarse con la propiedad UpdateMode, introducida en la clase TDBDataSet (del BDE), de upWhereAll, a upWhereChanged o upWhereOnly.

En el caso de las IBX, según recuerdo, las sentencias SQL generadas automáticamente para actualizar los registros en un TIBUpdateSQL, en el caso de insert y update comprenden solamente la llave primaria.

En cualquier caso, podrias modificar el comportamiento por defecto sobreescribiendo estas sentencias para incluir cualquier campo que sea de tu interes (incluso todos).

Me parece poco probable que los componentes dejen pasar por alto el hecho de que no se actualizara ningún registro en la BD, pero no me considero experto en el tema ni dispongo actualmente del tiempo para probarlo por mi mismo. Por lo tanto, dejo la idea, espero que vos hagas pruebas y nos saques de una buena vez de la duda.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #5  
Antiguo 30-07-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Puedes utilizar un ClientDataset para modificar los registros. Conectas tu IBQuery a un DatasetProvider y este a un ClientDataset. Cuando quieras hacer modificaciones las haces en el ClientDataset, y para pasar los cambios a la Base de Datos llamas al ApplyUpdates.

La ventaja es que puedes usar las opciones upWhereAll, upWhereChanged, upWhereKeyOnly que comentaba Juan Antonio (se configura en el DatasetProvider). Esto hace que se ejecute una instrucción distinta en función de la opción seleccionada, incluyendo solo la clave primaria en la sección Where, o bien la Clave primaria más los campos que se van a modificar y finalmente todos los campos.

NOTA: Te recomiendo utilizar upWhereChanged. Que solo te va a provocar un error si intentas modificar un campo que ya ha sido modificado por otro usuario.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #6  
Antiguo 30-07-2004
Halfo Halfo is offline
Registrado
 
Registrado: jul 2004
Posts: 9
Poder: 0
Halfo Va por buen camino
Siento volver a insistir, pero no se si consigo hacerme entender y transmitir mi duda, ya que todo el mundo acaba contestandome algo que ya sabia y que NO resuelve mi duda.

Respecto las dos ultimas contestaciones de jachguate y guillotmarc:
He hecho referencia al libro "La cara oculta de C++" porque es la unica lectura minimamente extensa y completa que tengo respecto al desarrollo de aplicaciones orientadas a BBDD en entornos RAD de Borland, ya se que esta un poco anticuado, pero todas las demas lecturas realizadas al respecto (Firebird/interbase,IBX,...) son documentos mucho más concretos o demasido generales y raramente hacen referencia a una metodologia consistente para el desarrollo. Por lo que mi base de conocimiento es un viejo libro + pequeñas ideas extraidas de manuales,articulos y respuestas del foro (si alguien tiene una buena recomendación de lectura que no se calle). En el libro "la cara oculta" se describen las actualizaciones optimistas como aquellas en que a la hora de editar los registros no se bloquean, se permite la edición concurrente y los problemas los tendrán los que intenten actualizar en segundo lugar ya que no encontraran el registro que estaban editando. Esto entiendo cuando leo:

Las dos aplicaciones pueden realizar las asignaciones al buffer de registro sin ningún tipo de problemas. Recuerde que este buffer reside en el ordenador cliente. La primera de ellas en terminar puede enviar sin mayores dificultades la petición de actualización al servidor. Sin embargo, cuando la segunda intenta hacer lo mismo, descubre que el registro que había leído originalmente ha desaparecido, y en ese momento se aborta
la operación mediante una excepción.


Pero el libro esta hablando de una tabla de del BDE y por eso menciona la propiedad UpdateMode donde especificar la forma de localizar el registro al actualizar. El libro tambien detalla lo que hace el BDE en realidad que no es mas que realizar un update con el WHERE para localizar el registro incluyendo la pKey o lo cambiado o todos los campos.
Bueno como el BDE esta anticuado y es muy 'pesado' , para conectarse a Interbase/Firebird actualemente lo mejor es utilizar IBX (o otros componentes directos IBO,IBPlus,...) y segun tengo entendido los componentes TIBTable, TIBQuery , TIBUpdateSQL existen por compatibilidad con el pasado y se debe usar TIBDataSet o TIBSQL. Luego el TIBDataSet nos oferece la posibilidad de configurar a nuestro antojo como actualizar nuestro dataser con ModifySQL por lo que podemos poner la misma sentencia SQL que pone el UpdateMode en el caso del BDE. Hasta aquí todo muy bien pero.....
El UPDATE FALLA y los componentes no me avisan!!!!!
He monitorizado con TIBSQLMonitor lo que esta pasando en el post:
Se realiza un update + un select + un fetch del registro.
En caso que no haya problema (no han modificado el registro) todo ok.
pero si observo el caso en que debería fallar el update obserbo:
Se realiza un update + un select + un fetch del registro + un PEQUEÑISIMO
SEOFReached. que supongo es el mensaje que da al realizar el fetch y no encontrar datos ,(curioso que del update no diga nada pero bueno)

No se si veis donde quiero llegar, intento realizar lo que yo entiendo como un control optimista de la concurrencia pero no puedo ya que no encuentro la forma de que se me avise que esta fallando algo (solo estoy exponiendo el caso del update, con el delete tambien pasa lo mismo, por suerte el insert no tiene esta problematica ).

A) ¿El planteamiento del control optimista es erronio?
B) ¿La implementación con estos componentes IBX es erronia?
C) ¿Me estoy dejando algo, y por eso no me saltan los fallos?
D) Ninguna de las anteriores.

Guillotmarc, de momento no quiero complicar más el tema con CachedUpdates y ApplyUpdates, que si utilizaré para los datos con master/detail, etc...
Responder Con Cita
  #7  
Antiguo 30-07-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Lamentablemente tu duda no te la puedo resolver. Simplemente es que estamos hablando de componentes BDE y IBX, y nunca he utilizado ninguno de ellos.

Solo he pretendido ayudarte, aconsejándote el uso de unos componentes que si conozco (los ClientDatasets).

NOTA: Utilizar un control optimista, me parece la forma más correcta de atacar una base de datos. Aunque como ya te he comentado, no puedo decirte que es lo que haces mal con IBX.

NOTA 2: El uso de Clientdatasets no tiene nada que ver con el modo CachedUpdates, aunque el concepto sea parecido.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
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 02:59:37.


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