Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Autocommit en ZConnection (https://www.clubdelphi.com/foros/showthread.php?t=82665)

jpgonzalez 31-03-2013 05:06:12

Autocommit en ZConnection
 
Buenas para todos... estuve leyendo varios hilos que hablan de este tema, pero no he podido encontrar la respuesta o solución al problema que estoy teniendo al insertar datos en la BBDD con ZConnection.

Para explicar lo que me esta pasando usaré el ejemplo de las inserciones a varias tablas seguidas:
factura: tabla donde se inserta el encabezado de la factura
facturadetalle: tabla donde se inerta el detalle (los articulos que se facturaron)
pagos: tabla donde se inserta la forma de pago de la factura
articulos: que se utiliza solo para actualizar el stock

Código Delphi [-]
//El codigo esta simplificado al maximo para que no se haga muy larga la parte de codigo, cuando el tema es la conexion

   try
      DmMain.ZConnection.StartTransaction;
         .................................
         QryInsertarFactura.ExecSQL;
         .................................
         QryInsertarDetalleFactura.ExecSQL;
         .................................       
         QryActualizarStock.ExecSQL;
         .................................
         QryInsertarPago.ExecSQL;

      DmMain.ZConnection.Commit;
   except
      DmMain.ZConnection.Rollback;
      ShowMessage('No se ha podido guardar la factura.');
      abort;
   end;

Con este codigo, tenia la propiedad autocommit de ZConnection en true, lo que me generaba un problema de inconsistencia al guardar los datos en la BBDD.
En el ejemplo anterior, primero se inserta la factura, luego el detalle, luego se actualiza el stock y por ultimo se inserta el pago.
Supongamos que la factura, el detalle, y el stock se guarda bien, pero surge un error al guardar el pago.
En teoria, al tener todo en un StartTransaction/Commit no deberia guardar nada, pero al ver la BBDD me encontraba que las tres tablas que no tuvieron error se habian guardado... no se les habia hecho el Rollback a estas tablas.

Buscando en el foro, encontré que habia que poner el autocommit en falso, para que esto no ocurriera.
Poniendo el autocommit en falso, me tiraba otro error: Invalid operation in non AutoCommit mode
Buscando y leyendo encontré que ese error era debido al StartTransaction, ya que ese comando no era necesario cuando el autocommit estaba en falso.

Acto seguido comente esa linea (DmMain.ZConnection.StartTransaction), y solo deje el commit al final de las inserciones, pero cuando hice esto surgio algo nuevo: los datos aparentemente se guardaban, ya que debbugeando el código se ejecutaba todo a la perfección, pero al revisar la BBDD los datos no estaban.
Como si hubiera hecho un commit en memoria, y no lo hubiese posteado en la base.
Seguí buscando y leyendo pero no encontré la razón por la cual pasaba esto... encontre otros hilos que hablaban de commit suaves y commit duros, pero no logré encontrar la respuesta de porque el commit no posteaba en la base.

Mi problema, en resumen es el siguiente:
Si dejo el autocommit en true corro riesgo de generar inconsistencias en los datos de la BBDD, pero si lo pongo en false no puedo lograr que los datos que inserto se posteen en la base.

Espero haber sido claro... abrazo para todos!

Aclaracion; programo en Delphi XE, con ZConnection, MySQL y tablas InnoDB... y la propiedad del ZConnection--> TransactIsolationLevel = tNone

jpgonzalez 03-04-2013 16:07:11

Buenas para todos...
Les comento que la version de Zeos que tenia era la 7.0.0-dev... en un foro de Zeos me dijeron que pruebe con la 7.0.3-stable, pero sigo teniendo el mismo inconveniente con el autocommit tanto en false como en true.

Será un problema de try/except???
No entiendo por que pasa que si tengo todas las inserciones dentro de un starttransaction/commit, inserte solo parte del bloque en lugar de TODO o NADA.

Seguire buscando... por ahora sin respuesta ni solucion. Abrazo!!!

jorge82 04-04-2013 02:34:39

Yo utilizo la versión 7.0.3-stable con Firebird y Delphi 7 y siempre dejo ZConnection.AutoCommit en True, y luego si quiero manejar las transacciones explicitas lo hago con
Código Delphi [-]
ZConnection.StartTransaction;
try
   ...
  ZConnection.Commit;
except
  ZConnection.Rollback;
end;

es decir como en tu primer post, solo que dejando la propiedad AutoCommit en True y nunca he tenido problemas con la transacción o se guardan todos los cambios o no se guarda nada, eso si la propiedad TransactionIsolation la pongo a tiReadCommitted.

jpgonzalez 04-04-2013 07:21:26

Cita:

Empezado por jorge82 (Mensaje 458024)
Yo utilizo la versión 7.0.3-stable con Firebird y Delphi 7 y siempre dejo ZConnection.AutoCommit en True, y luego si quiero manejar las transacciones explicitas lo hago con
Código Delphi [-]
ZConnection.StartTransaction;
try
   ...
  ZConnection.Commit;
except
  ZConnection.Rollback;
end;

es decir como en tu primer post, solo que dejando la propiedad AutoCommit en True y nunca he tenido problemas con la transacción o se guardan todos los cambios o no se guarda nada, eso si la propiedad TransactionIsolation la pongo a tiReadCommitted.


Grande Jorge, grosoooooooooo!!!!
Poniendo la propiedad del TransactIsolationLevel en tiReadCommited anduvo a la perfeccion!!!.
Muchisimas gracias, la verdad que habia buscado en muchos lugares, posteado en ingles en foros de Zeos, Reconfigurado el MySQL, etc... ya no sabia mas que hacer.
Nuevamente, muy agradecido... abrazo!!!

jorge82 04-04-2013 09:28:20

De nada, que bueno que ya se resolvió.


La franja horaria es GMT +2. Ahora son las 21:09:21.

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