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 10-11-2011
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
Desesperación Bloqueos

Hola o nunca tengo problemas o los tengo todo seguidos.

Tengo problemas con los bloqueos de registros y no se por que. Tengo una aplicacion que recibe paquetes UDP para meter lineas en una centralita para hacer llamadas. Esta aplicacion cada vez que recibe un paquete lanza un SP en la BD que selecciona el registro que cumpla una serie de propiedades e inmediatamente despues lo actualiza marcandolo para no llamarlo, os paso el codigo:

Código SQL [-]
SELECT  FIRST 1 CAST(TELEFONO AS CHAR(9)) 
FROM  MOVILES_POPUP
WHERE
ID_CAMPANIA = 'LEADS' AND PRIORIDAD = 1 AND (HORA_PROX_CONTACTO < CURRENT_TIME )
ORDER BY   HORA_PROX_CONTACTO desc, FECHA_SOL_CLIENTE DESC,HORA_SOL_CLIENTE DESC,   HORA_SOL_CLIENTE DESC,FECHA_PROX_CONTACTO DESC
INTO  :TELEFONO_1;

UPDATE MOVILES_POPUP SET PRIORIDAD = 2,HORA_PROX_CONTACTO = CURRENT_TIME + 3600 WHERE TELEFONO = :TELEFONO_1;

suspend;


END;

Los paquetes se reciben cada segundo, que es tiempo suficiente para ejecutar el SP. Pero no se porque me sale el siguiente mensaje:


Uso Firebird 2.5, FibPlus, he leido 300 manuales, he configurado la transaccion de mil maneras y nada. Estoy algo desesperado.

Si alguien tiene algo de luz que me ilumine.
Responder Con Cita
  #2  
Antiguo 10-11-2011
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.

Realiza las transacciones lo más cortas posibles. No dejes transacciones abiertas, cuando tengas que realizar uno de estos cambios, abre una nueva transacción, llama al procedimiento almacenado e inmediatamente después cierra la transacción.

Los conflictos de bloqueo solo ocurren cuando desde una transacción se intenta actualizar un registro modificado por otra transacción posterior a la apertura de la primera transacción. Si realizas las transacciones de la forma que te he dicho, la única probabilidad de colisión ocurre cuando dos estaciones intentan modificar el mismo registro durante las mismas milésimas de segundos. Vamos, prácticamente nunca (durante años programando así, apenas recuerdo haber encontrado nunca bloqueos).

NOTA: Esta es una de las razones por las que me encanta utilizar ClientDatasets, porqué con ellos no se dejan transacciones abiertas mientras el usuario consulta/modifica datos.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #3  
Antiguo 10-11-2011
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
Hola, estoy usando CDS, este está asociado a su DataSetProvider, este a su TTransaction y este a su DataSet.

En el evento AfterApplyUpdate del DataSetProvider, tengo lo siguiente:

Código Delphi [-]
if TContacto_leads.InTransaction then
begin
        TContacto_leads.Commit;
end;

¿Donde debo abrir la nueva transaccion? ¿en el CDS? ¿en el servidor de capa intermedia? Estoy algo perdido.


Saludos
Responder Con Cita
  #4  
Antiguo 10-11-2011
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
La solución es gratuita, pero lleva tiempo. La tienes en los documentos de Interbase/Firebird (data definition guide, etc) en http://www.ibphoenix.com/resources/documents/general

Lo siento pero no hay magia, tus necesidades pueden ser diferentes a las mías, por eso no puedo aconsejarte. Si te fijas casi nadie pregunta ese tipo de cosas porque lee la documentación, se empapan de todo lo que necesitan entender, configurar, etc y en este foro solo se viene a preguntar por "ideas de procedimientos almacenados", trucos de SQL, de programación y tal.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #5  
Antiguo 10-11-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.052
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Paisano, Rockin, aunque estés desesperado, pero recuerda poner un título descriptivo a tu pregunta. Gracias, amigo
Responder Con Cita
  #6  
Antiguo 10-11-2011
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Cita:
Empezado por Rockin Ver Mensaje
Hola, estoy usando CDS, este está asociado a su DataSetProvider, este a su TTransaction y este a su DataSet.

En el evento AfterApplyUpdate del DataSetProvider, tengo lo siguiente:

Código Delphi [-]if TContacto_leads.InTransaction then begin TContacto_leads.Commit; end;


¿Donde debo abrir la nueva transaccion? ¿en el CDS? ¿en el servidor de capa intermedia? Estoy algo perdido.


Saludos
No es necesario ningún código de este tipo, puesto que el Provider del ClientDataset ya abre y cierra una transacción por si mismo.

Así que simplemente deja la transacción cerrada.

Naturalmente tienes más código. Primero porqué desde un CDS no puedes lanzar SP como el que comentas en el primer post, y segundo, porqué si te saltan bloqueos, es que estás manteniendo transacciones abiertas.

Si tienes todas las transacciones cerradas, no te puede saltar ningún error de bloqueo por abrir momentaneamente una transacción para realizar un cambio sobre un registro.

Recuerda, si te salta un bloqueo es porqué intentas modificar un registro desde una transacción que ha estado abierta desde antes que otra transacción haya modificado el mismo registro.

Revisa tu código, y cierra las transacciones que estás dejando abiertas. Cuanto menos tiempo queden abiertas, menos problemas tendrás.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #7  
Antiguo 10-11-2011
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
Perdon Casimiro Notevi.

Seguire probando y leyendo a ver si me aclaro, pero no lo veo, creo que está todo correcto. Algo se me está escapando.

Si guillotmarc , tengo más codigo el procedimiento lo llamo así:

Código Delphi [-]
       with datDatosRemoto.CDSLeads do
        begin
                Close;
                CommandText:= 'select telefono from SP_PEDIR_CONTACTO_LEADS';
                Open;
                Execute;
            
        end;
:

El codigo que tengo puesto en el Provider lo vi en el libro la cara oculta de delphi 6. En el resto de transacciones ma va biem pero aqui al ser transacciones muy seguidas puede que me falle por eso. No se que hacer............

Última edición por Rockin fecha: 10-11-2011 a las 21:00:17.
Responder Con Cita
  #8  
Antiguo 10-11-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.052
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Es que, como dice guillotmarc, un deadlock sólo se produce cuando hay otra transacción abierta sobre el mismo registro, grabando. No importa las de lectura.
Así que sólo queda el que las revises, porque seguro que algo se te ha escapado por ahí.
Responder Con Cita
  #9  
Antiguo 10-11-2011
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.

Cita:
Empezado por Rockin Ver Mensaje
... .... ... . En el resto de transacciones ma va biem pero aqui al ser transacciones muy seguidas puede que me falle por eso. No se que hacer............
Creo que ya te lo he insistido antes : No dejes transacciones abiertas y la posibilidad de bloqueos se vuelve prácticamente nula (solo pueden ocurrir cuando realmente se intente modificar el mismo registro en los mismos milisegundos).

Se te están quedando abiertas transacciones, y hasta que no lo corrijas seguirás teniendo problemas de bloqueos.

Puedes empezar verificando el estado de todas tus transacciones antes de lanzar esa modificación de registros (añade unas pocas líneas de código que te avisen si alguna de las transacciones está abierta en ese momento). Si es necesario también puedes utilizar las tablas de monitorización de Firebird para ver las transacciones que llevan más tiempo abiertas.

Ejemplo : http://www.firebirdfaq.org/faq352/

Mantener abiertas transacciones de lectura no es ningún problema, pero todas las escrituras deberían ejecutarse en el menor tiempo posible : abrir transacción, modificar registros y finalizar transacción inmediatamente. Es la única forma de evitar bloqueos, y es que es lógico que haya bloqueos cuando las transacciones se alargan, ¿ que se supone que debería hacer el motor de base de datos en estas situaciones ?, para respetar la integridad de los datos implicados en la transacción no tiene otro remedio que activar un deadlock (conflicto).

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 10-11-2011 a las 23:03:01.
Responder Con Cita
  #10  
Antiguo 10-11-2011
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 Casimiro.

Cita:
Empezado por Casimiro Notevi Ver Mensaje
Es que, como dice guillotmarc, un deadlock sólo se produce cuando hay otra transacción abierta sobre el mismo registro, grabando. No importa las de lectura.
Así que sólo queda el que las revises, porque seguro que algo se te ha escapado por ahí.
Otra posibilidad de deadlock es cuando tu misma transacción actual lleva demasiado tiempo abierta (incluso sin haber hecho aún la menor escritura).

Si una segunda transacción ha modificado entretanto un registro, aunque esa segunda transacción de modificación ya haya finalizado hace tiempo, tu no podrás volver a modificar el mismo registro dentro de la transacción actual. Puesto que tienes un conflicto entre la versión del registro que tienes en la transacción actual, y el registro real en la base de datos (que actualizó la segunda transacción, ya cerrada y finalizada).

No sé si me he sabido explicar .

Por eso no me gustan los componentes como FibPlus, IBX, etc. ..., porqué prácticamente te obligan a mantener abiertas transacciones, y eso es una fuente segura de problemas.

Afortunadamente enlazarlos con ClientDatasets te solventa todos estos problemas, puesto que ya no necesitas dejar transacciones abiertas ni siquiera para lectura (que son las transacciones que se convertirán en problemáticas al querer pasarlas a transacciones de escritura cuando el usuario ha finalizado de trabajar con esos datos).

Las transacciones nunca se diseñaron para que estuvieran abiertas mientras el usuario trabaja con la información relacionada. Se supone que sirven solo para agrupar un conjunto de escrituras, y poder asegurar de que se hacen de forma conjunta (de forma que los datos sean coherentes a unas reglas de negocio).

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 10-11-2011 a las 23:22:12.
Responder Con Cita
  #11  
Antiguo 10-11-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.052
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Sí, se entiende.
Responder Con Cita
  #12  
Antiguo 11-11-2011
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
Hola , ante todo gracias por ayudarme y perdonadem si estoy dando mucho el coñazo.

Cita:
Empezado por guillotmarc Ver Mensaje

Creo que ya te lo he insistido antes : No dejes transacciones abiertas y la posibilidad de bloqueos se vuelve prácticamente nula (solo pueden ocurrir cuando realmente se intente modificar el mismo registro en los mismos milisegundos).

Saludos.
No te enfades conmigo, guillotmarc, es que no se donde se queda la transaccion abierta o por que, es decir en el evento Execute del CDS tengo puesto CDS.ApplyUpDates(-1) y en el DataSset, he puesto la propiedad Autocommit a true. Teoricamente al realizar el commit, se cierra la transacción ¿no? ¿O me estoy equivocando en este concepto?. LLevo cuatro años con estos componentes y nunca me ha pasado este problema y ando muy perdido. Es una aplicacion Cliente-Servidor con 3 servidores de capa intermedia balanceados por carga.
Responder Con Cita
  #13  
Antiguo 11-11-2011
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.

Cita:
Empezado por guillotmarc Ver Mensaje
Puedes empezar verificando el estado de todas tus transacciones antes de lanzar esa modificación de registros (añade unas pocas líneas de código que te avisen si alguna de las transacciones está abierta en ese momento). Si es necesario también puedes utilizar las tablas de monitorización de Firebird para ver las transacciones que llevan más tiempo abiertas.

Ejemplo : http://www.firebirdfaq.org/faq352/
¿ En que parte te pierdes ?.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #14  
Antiguo 14-11-2011
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
No se donde estoy fallando, teoricamente todas las transacciones se deben cerrar rapidamente. Le voy a poner un timeout al componente transaction a ver si así soluciono el tema. Lo he revisado todo mil veces.

Gracias y ya os contaré.

Saludos.
Responder Con Cita
  #15  
Antiguo 14-11-2011
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Sí, yo siempre configuro mis transacciones con un timeout de 1 milisegundo (lo puedes hacer con toda seguridad, incluso aunque tus sentencias tarden más de 1 milisegundo en ejecutarse, puesto que este timeout solo se activa cuando la aplicación está en espera).

¿ Has verificado las transacciones más largas en curso ? (tal y como indica el artículo enlazado). Puede ser que el conflicto lo provoquen transacciones que ni siquiera sean de tu aplicación, sino conexiones de terceros a la misma base de datos.

¿ Has probado a añadir unas pocas líneas de código al actualizar, que te avisen de si algunas otras de tus transacciones están abiertas ?.

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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Webservice + DESESPERACION TOTAL delphijm Providers 4 03-08-2010 00:01:09
Desesperación Modificacion TDBAdvStringGrid Rockin Conexión con bases de datos 6 12-03-2008 12:21:48
Desesperacion DBLookupComboBox Rockin Firebird e Interbase 8 10-10-2007 01:37:52
bloqueos optimistas VS bloqueos pesimistas flystar Conexión con bases de datos 1 21-06-2007 09:31:13
Desesperacion con FReports Josemarg Impresión 0 28-02-2007 18:26:01


La franja horaria es GMT +2. Ahora son las 02:52:17.


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