PDA

Ver la Versión Completa : Problemilla con transacciones e IBDataSet


RESP 3.0
27-05-2005, 21:39:08
Que tal señores les planteo mi situacion:

Utilizo D6 IBX FB 1.5.2

Tengo un IBDataset el cual tiene un campo que sufre modificaciones dentro de un SP, el problema que tengo es:

Abro la IBDataset y pongo en modo de edicion un registro (simulando que se esta modificando) y en otra instancia de la aplicacion se ejecuta el SP que modifica el campo calculado del IBDataset, el problema es que cuando Posteo el IBDataset no considera los cambios realizados desde la otra transaccion (otro cliente), como puedo hacer o cual es el nivel de aislamiento a utilizar, actualmente utilizo read_committed y wait en todas mis transacciones.

De antemano, gracias por la ayuda

AGAG4
28-05-2005, 03:05:50
Ya usastes un Commit ó CommitRetaining del componente ibTransaction ????

Saludos.

RESP 3.0
30-05-2005, 18:39:23
Primero que todo, gracias por la atencion, fijate que si siempre utilizo ambas dependiendo de la situacion, el problema en si es como hago para bloquear un registro desde las IBX?, por ejemplo cuando lo coloquen en modo de edicion que automaticamente se bloquee.

AGAG4
30-05-2005, 23:03:24
En el tipo de aislamiento de la Transacción puedes cambiarle de nowait a wait, presiona el boton derecho del ratón sobre el componente ibTransaction y entra a Transaction Editor y en el aislamiento Read Commited viene lo que te digo....

Esto significa que cuando 2 PC's esten usando 1 mismo registro una de ellas tiene que esperar a que desocupe este mismo registro.

Saludos.

jachguate
31-05-2005, 01:01:41
Firebird usa un modelo de bloqueos "optimista", por lo que un registro no será bloqueado con el simple hecho de comenzar su edición.

Podes simular un entorno de bloqueos "pesimista" haciendo lo que se conoce como una actualización en falso sobre el registro que te interesa, de manera que este sea efectivamente bloqueado.

Podrias, en el evento AfterEdit, por ejemplo, lanzar el siguiente query:


Update Tabla
set campo = campo
where llave = ValorLlave;


como ves, en realidad nada se cambiará en el registro (de alli el nombre de actualización en falso), sin embargo sobre este será puesto un bloqueo que se liberará con el próximo commit/rollback.

Si dejas las transacciones como nowait, te saltará una excepción inmediatamente trates de hacer esto, que ya será cosa de "atrapar" para realizar las acciones pertinentes, por ejemplo, no permitir la edición del registro.

algo como:


Procedure TDataModule1.TablaAfterUpdate(Parametros...);

Begin
try
LanzarActualizaciónEnFalso;
except
// dio error!
Tabla.Cancel; // Evitamos que quede en modo de edición
raise; // lanzamos nuevamente el error para que se maneje afuera
end;
end;


Desde mi punto de vista, con esto estas echando a perder una de las grandes ventajas de firebird (y de muchas de las bases de datos relacionales serias)... asi que te aconsejo pensarla otras dos veces y ver si mejor cambias tu forma de pensar para aprovechar esta gran característica.

Hasta luego.

;)

inferno
31-05-2005, 17:31:52
hola jachguate que tal cuando tu dices "Desde mi punto de vista, con esto estas echando a perder una de las grandes ventajas de firebird (y de muchas de las bases de datos relacionales serias)... asi que te aconsejo pensarla otras dos veces y ver si mejor cambias tu forma de pensar para aprovechar esta gran característica."

tu quieres decir que firebird ejecuta el bloqueo y desbloque por si solo para resguardar la integridad de la data y evitar falsa lectura de datos.

tambien se puede decir que firebird es multiusuario (varias aplicaciones conectadas a una misma base de datos me explico)

jachguate
31-05-2005, 17:58:58
No soy bueno dando argumentos... pero San Google (http://www.sangoogle.com) si que lo es... :D

Por lo pronto, y aunque el enfoque no es precisamente el mismo, este artículo (http://www.marteens.com/trick4e.htm) de marteens también habla algo del tema.

Hasta luego.

;)

lbuelvas
31-05-2005, 20:49:38
Hola foro,

No sea si el caso aplica, pero en las nuevas aplicaciones que estoy desarrollando me toco hacer algo especial con los IBDataset.

Resulta que si tienes campos calculados o que son actualizables por los triggers e incluso por algunos procedimientos almacenados, estos campos no deberian estar en la propiedad ModifySQL.

Esto se debe a que, cuando tu colocas un registro en edicion con un objeto IBDataset, tienes del lado del cliente el valor del campo en el momento que abriste el IBDataset (Cliente1).

Si el otro usuario (Cliente2) ejecuto el procedimiento y cambio el valor del campo, cuando el Cliente1 de grabar (Dataset.Post) va a mandar hacia el motor de base de datos el valor que habia traido originalmente, es decir, reescribiria con un valor antiguo.

En cierto aplicativo me pasaba que los saldos de los clientes en un sistema de facturacion con una frecuencia de uno o dos clientes al mes, se descuadraban, y busque y busque y nada, pues resulta que otro proceso actualizaba el saldo y casualmente habia otro usuario modificando algun campo menor del cliente como el telefono o direccion. La solucion, si el campo es mantenido por triggers o procedimientos almacenados, no debe ser actualizable desde el cliente.

En algunos sistemas se necesita que un procedimiento actulice datos , por ejemplo, si se ha descuadrado un invetario, razon en la que no deberia haber usuarios conectados para realizar dicha actividad.

Podrias dar mas detalles para ayudar con alguna solucion ?

RESP 3.0
31-05-2005, 22:51:19
Pues gracias vos Jachguate, voy a probar con los bloqueos optimistas y de alguna manera informarle e los usuarios que el registro esta bloqueado, la verdad me parece un poco chapucera esa forma de manejar datos con los componentes IBX, lo que se me ocurre tambien es utilizar TUpdateSQL, ya que estos me permitiran realizar la lectura de datos, y al momento de actualizar realizar una relectura de datos para poder actualizar correctamente. Ya probare y colocare aca mis resultados.

Gracias

RESP 3.0
03-06-2005, 02:06:59
Bueno gracias por las respuestas quiero contarles que segui los consejos de Ibuelvas de no colocar en el ModifySQL los campos que son modificados por medio de SP o Triggers y todo va a la perfeccion siempres seguire con mas pruebas y cualquier cosa por aca me veran

Hasta Luego y gracias