![]() |
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:
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. |
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. |
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:
¿Donde debo abrir la nueva transaccion? ¿en el CDS? ¿en el servidor de capa intermedia? Estoy algo perdido. Saludos |
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. |
Paisano, Rockin, aunque estés desesperado, pero recuerda poner un título descriptivo a tu pregunta. Gracias, amigo :)
|
Cita:
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. |
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í:
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............ |
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í. |
Hola.
Cita:
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. |
Hola Casimiro.
Cita:
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. |
Sí, se entiende.
|
Hola , ante todo gracias por ayudarme y perdonadem si estoy dando mucho el coñazo.
Cita:
|
Hola.
Cita:
|
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. |
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. |
La franja horaria es GMT +2. Ahora son las 06:23:29. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi