PDA

Ver la Versión Completa : Bloqueo del programa, abierto varias veces


GINMARMENOR
05-12-2022, 23:06:50
Buenas, tengo Delphi 2010 y trabajo de Firebird 2.5, la base de datos con la que trabajo la creo con IbExpert, con lo que trabajo con IbDatabase e Ibtables.

Tengo creado dos base de datos IbDatabaseMaestro asociado con su transaccionMaestro e IbDatabasePedidos con su transaccionPedidos, de cada base de datos he creado 15 Ibtables, en total 30 Ibtables.

Algunas Ibtables tienen 40 campos, otras 20.

¨Las Ibdatabase, como las transacciones, como las IbTables están centradas en un formulario "datamodule" todas juntas y de ahí abro en cada formulario la Base de datos, la Transaccion y la Tabla que necesito y al cerrar el formulario cierro la Ibdatabase, la Transaccion y las Ibtables que he abierto.

Cuando abro el programa, los IbDatabase no están conectadas, las Transacciones y las Ibtables no están activas y como he dicho las abro cuando las necesito y las cierro cuando cierro el formulario que las abrió.

Cuando abro el programa una sola vez, todo funciona bien, abro todos los formularios los cierro, y cuando acabo se cierra el programa en 3 segundos sin problemas.

Pero viendo que cuando abro el programa dos o tres veces en el mismo ordenador al ir cerrando se me bloquea o tarda mucho tiempo en cerrar he estado buscando donde podría estar el problema pero no lo encuentro, el hecho que al abrir el programa, todas las base de datos, transacciones y tablas están inactivas, y esto haría que se cerrara el programa fácilmente pero no lo hace.

No sé si al tenerlo todo concentrado en un Datamodule sea un problema, o al abrir al programa hace algúna gestion interna que se me escapa.

Os agradeceria vuestras opiniones, ya que es muy importante para mi solucionarlo

Gracias.

ASAPLTDA
06-12-2022, 11:55:10
Cuando abro el programa, los IbDatabase no están conectadas, las Transacciones y las Ibtables no están activas y como he dicho las abro cuando las necesito y las cierro cuando cierro el formulario que las abrió.

la cierro cuando cierro el formulario indica que si hay cambios en la tabla permanecen abiertas? la transaccion se compromete por cada cambio o solo cuando se cierra la forma ?

la transaccion, el commit , rollback es iniciada/ejecutada por el programa?

podria ampliar mas la informacion de como son las consultas ?
que tipo de componentes se conecta a la base de datos?

duilioisola
06-12-2022, 14:31:03
Parece un problema con la vida de las transacciones...
Ejemplo con dos instancias de la aplicación:
Instancia 1
Conecta
Transaccion.StartTransaction (ReadWrite)

Instancia 2
Conecta
Transaccion.StartTransaction (ReadWrite)

Instancia 1
Insert Tabla LOG (Usuario = 1, FechaEntrada = 'NOW')

Instancia 2
Insert Tabla LOG (Usuario = 2, FechaEntrada = 'NOW')
(Quedará esperando hasta que la Instancia 1 haga commit)

Instancia 1
Commit

Instancia 2
Commit

Dependiendo de los componentes que utilices hay opciones diferentes...

Utiliza transacciones ReadOnly donde sea posible (Evitan este problema).
Las transacciones que escriben (UPD, INS, DEL) deben ser lo más corta posibles.
Prueba finalizar transacciones con CommitRetaining (es algo así como hacer commit y abrir inmediatamente otra transacción)

GINMARMENOR
06-12-2022, 14:39:12
Los componentes que uso son TIbDatabase, TIbTransaction, TIbTable, TDatasurce, todos están incluidos en un TDatamodule, en dicho TDatamodule tengo dos TibDatabases y a cada uno su TIbTransaction y unas 20 TIbTables con sus 20 TDatasources enlazadas a su TibDatabase correspondiente.

IbTransaction está configurado en su Transation Editor de la siguiente manera:


Read_commited
Rec Version
Nowait

y tengo marcado en propiedades el Read Commited.


En un principio siempre TibDatabase no está conectado, TibTransaction y TibTAble no están activos.

Al abrir un formulario cualquiera de los muchos que tengo hago lo siguiente en OnShow:


dat.datamodule1.IbDatabase1.Conected=true;
dat.datamodule2.IbDAtabase2.Conected=true;
dat.datamodule1.TibTransaction1.Active=true;
dat.datamodule2.TibTransaction2.Active=true;

dat.datamodule1.IbTable1.Active=true;
...
dat.datamodule1.Ibtable4.Active=true;



Al cerrar el formulario en OnClose;


dat.datamodule1.TIbTransation1.Commit;
dat.datamodule1.TibTranssation2.commit;

dat.datamodule1.IbTable1.Active=false;
...
dat.datamodule1.Ibtable4.Active=false;

dat.datamodule1.IbDatabase1.Conected=false;
dat.datamodule1.IbDatabase1.Conected=false;
dat.datamodule1.TibTransaction1.Active=false;
dat.datamodule1.TibTransaction2.Active=false;



Bien ahora en el manejo de grabar registro a registro con el Boton Grabar hago lo siguiente:



begin
try
dat.datamodule1.IbTable1.Append;
dat.datamodule1.IbTable1.Fields[0].AsString:=edit1.text;
...
dat.datamodule.IbTable1.Fields[20].AsString:=Edit20.text;
dat.datamodule.IbTabl11.post;
Except
dat.Datamodule.IbTransaction1.CommitRetaining;


Bien ahora trabajo con el programa en modo monopuesto y funciona bien, graba los 50 o 100 registros después cierro el programa y todo bien se cierra enseguida sin problemas.

Ahora bien, el programa lo tengo en el PC1, y también en el PC2, PC1 hace de servidor donde tengo los datos, el PC2 está con conectado al PC1 mediente el protocolo de conexión Ip, y tengo acceso a la base de datos del PC1 perfectamente.

Si trabajo sólo con el Pc1 todo funciona bien, grabo sin problemas,
Si trabajo sólo con el Pc2 todo funciona también bien, grabo, modifico sin problemas y me salgo del programa sin problemas, igual que con el Pc1.

Pero si abro el programa con los dos Pc's, a la vez puedo entrar bien, ver informes sin problemas, pero a la hora de modificar o dar de alta un registro o borrar se queda pillado y bloqueado sin posibilidad de avanzar, la idea es de poder modificar en ambos Pc's, que grabara y cerrara la aplicación sin bloquearse o quedar pillado.
Sería de gran ayuda ver en qué puedo fallar, Gracias

duilioisola
07-12-2022, 09:50:57
Parece que solo haces Commit de la transacción si falla.

Deberías utilizar un bloque try..finally.
La diferencia es que el bloque FINALLY siempre se ejecuta (se ejecuta si el bloque TRY finaliza correctamente o falla).
El bloque EXCEPT solo se ejecuta si falla.

Si este es el caso, no estarás "cerrando" la transacción hasta que cierres el formulario, que a su vez hace commit y cierra tablas y base de datos.


begin
try
dat.datamodule1.IbTable1.Append;
dat.datamodule1.IbTable1.Fields[0].AsString:=edit1.text;
...
dat.datamodule.IbTable1.Fields[20].AsString:=Edit20.text;
dat.datamodule.IbTabl11.Post;
finally {Except}
dat.Datamodule.IbTransaction1.CommitRetaining;

GINMARMENOR
07-12-2022, 23:22:40
Perdón ha sido un error de sintaxis,

Utilizaba Finally en vez de Except.

Parece ser que está bien la extructura, tendrá que ser en algún otro detalle, tengo dos Ibdatabase y dos Transacciones y a cada una unas 20 tablas con 40 campos cada tabla, y todo está en un datamodule, aunque están todas cerradas, se supone que el programa se queda liberado puede cerrar fácilmente y no quedarse bloqueado cuando está abierto dos o más veces el programa, pero quizás internamente algo abre que no controlo y se queda pillado de alguna forma.

Gracias,

Casimiro Notevi
08-12-2022, 11:14:30
Perdón ha sido un error de sintaxis,
Utilizaba Finally en vez de Except.
Pero no hagas eso, sólo copia tu código ;)

GINMARMENOR
08-12-2022, 20:45:29
Este sería el código

Los componentes que uso son TIbDatabase, TIbTransaction, TIbTable, TDatasurce, todos están incluidos en un TDatamodule, en dicho TDatamodule tengo dos TibDatabases y a cada uno su TIbTransaction y unas 20 TIbTables con sus 20 TDatasources enlazadas a su TibDatabase correspondiente.

IbTransaction está configurado en su Transation Editor de la siguiente manera:


Read_commited
Rec Version
Nowait

y tengo marcado en propiedades el Read Commited.
En un principio siempre TibDatabase no está conectado, TibTransaction y TibTAble no están activos.

Al abrir un formulario cualquiera de los muchos que tengo hago lo siguiente en OnShow:


dat.datamodule1.IbDatabase1.Conected=true;
dat.datamodule2.IbDAtabase2.Conected=true;
dat.datamodule1.TibTransaction1.Active=true;
dat.datamodule2.TibTransaction2.Active=true;

dat.datamodule1.IbTable1.Active=true;
...
dat.datamodule1.Ibtable4.Active=true;


Al cerrar el formulario en OnClose;



dat.datamodule1.TIbTransation1.Commit;
dat.datamodule1.TibTranssation2.commit;

dat.datamodule1.IbTable1.Active=false;
...
dat.datamodule1.Ibtable4.Active=false;

dat.datamodule1.IbDatabase1.Conected=false;
dat.datamodule1.IbDatabase1.Conected=false;
dat.datamodule1.TibTransaction1.Active=false;
dat.datamodule1.TibTransaction2.Active=false;



Bien ahora en el manejo de grabar registro a registro con el Boton Grabar hago lo siguiente:


begin
try
dat.datamodule1.IbTable1.Append;

dat.datamodule1.IbTable1.Fields[0].AsString:=edit1.text;
...
dat.datamodule.IbTable1.Fields[20].AsString:=Edit20.text;

dat.datamodule.IbTable1.post;
Finally
dat.Datamodule.IbTransaction1.CommitRetaining;


Bien ahora trabajo con el programa en modo monopuesto y funciona bien, graba los 50 o 100 registros después cierro el programa y todo bien se cierra enseguida sin problemas.

Ahora bien, el programa lo tengo en el PC1, y también en el PC2, PC1 hace de servidor donde tengo los datos, el PC2 está con conectado al PC1 mediente el protocolo de conexión Ip, y tengo acceso a la base de datos del PC1 perfectamente.

Si trabajo sólo con el Pc1 todo funciona bien, grabo sin problemas,
Si trabajo sólo con el Pc2 todo funciona también bien, grabo, modifico sin problemas y me salgo del programa sin problemas, igual que con el Pc1.

Pero si abro el programa con los dos Pc's, a la vez puedo entrar bien, ver informes sin problemas, pero a la hora de modificar o dar de alta un registro o borrar se queda pillado y bloqueado sin posibilidad de avanzar, la idea es de poder modificar en ambos Pc's, que grabara y cerrara la aplicación sin bloquearse o quedar pillado.
Sería de gran ayuda ver en qué puedo fallar, Gracias

duilioisola
12-12-2022, 15:18:49
Para descartar el tema de transacciones haz la siguiente prueba:


PC1 Enciende aplicacion/ conecta
PC2 Enciende aplicacion/ conecta
PC1 inserta/modifica un registro
PC2 inserta/modifica un registro.
En este punto el PC2 debería estar bloqueado, esperando a quela transaccion sea liberada.
PC1 desconecta (cierra la aplicación)
PC2 debería responder en este momento y permitirte seguir insertando/editando registros.

GINMARMENOR
27-12-2022, 22:13:43
Es algo SuperRaro, ya que he conseguido con las indicaciones que me habéis dado en Transacciones que el PC1 y PC2 trabajen juntos, meto pedidos trabajando los dos a la vez, grabando, modificando registros de forma simultánea sin problemas, el problema viene cuando uno de los dos PC el que sea, después de cerrar todos los formularios que se han abierto llego al formulario principal, al cerrar este formulario y por ende la aplicación se queda bloqueado.

No sé qué hace internamente al cerrar el formulario Principal, que al cerrarlo se queda bloqueado eternamente, teniendo en cuenta que el formulario principal sólo está compuesto por un MainMenu, con las pestañas para ir abriendo los distintos formularios de los que cuenta el programa.

Eso sí, lo registros que he insertado, modificado o eliminado se quedan grabados, pero la aplicación se bloquea al cerrar el formulario Principal.

Gracias.

Casimiro Notevi
27-12-2022, 22:46:03
¿Algún mensaje de error?

GINMARMENOR
28-12-2022, 21:06:11
No, sólamente se bloquea o a veces tarda 10 minutos en cerrar el formulario principal o el programa, y todo lo demás lo hace bien toda la dinámica de insertar, modificar eliminar registros, pero al cerrar para sailr del programa se bloquea o tarda 10 minutos eso sí si lo fuerzo a cerrar con el administrador de tareas por ejemplo se cierra y todo queda grabado no se pierden datos, esto ocurre cuando hay 2 Pc conectados en la misma base de datos si hubiera sólo uno no ocurre.

Casimiro Notevi
28-12-2022, 21:35:57
Como no nos pases el programa para probar :confused: