Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus-es / 2010-05

zeos-firebird: ejemplo transacciones

26 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Paola Bruccoleri

Hola..
alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros en varias tablas (usando o no sp) y que queden en la misma transacci�n?? quisiera ver c�mo lo est�n resolviendo.

esto es lo que yo hago:

   DBMain.fdb.AutoCommit:= false;
   try
     DBMain.qry.Close;
     DBMain.qry.SQL.Text:= 'update numeros set boletas =
'+IntToStr(nComprob+1);
     DBMain.qry.ExecSQL;
   except
     MessageDlg('Error', 'Hay error ', mtWarning, [mbOk], 0);
     DBMain.fdb.Rollback;
   end;
   ..... varias sentencias: inserts, updates.... todas entre try/except
   DBMain.fdb.Commit;
   DBMain.fdb.AutoCommit:= true;

Si uso un generador para incrementar el contador de comprobantes, se supone que si todo el proceso de grabar est� dentro de la misma transacci�n, puedo seguir consultando por el valor del generador, que no se me va a modificar, no?

chauuuuuuuuuu

Reply by email

Maxi
to Paola Bruccoleri

El 6 de mayo de 2010 13:51, Paola Bruccoleri
<pbruccoleri en adinet.com.uy>escribi�:

Show quoted text 39 lines
Hola.. alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros en varias tablas (usando o no sp) y que queden en la misma transacci�n?? quisiera ver c�mo lo est�n resolviendo. esto es lo que yo hago: DBMain.fdb.AutoCommit:= false; try DBMain.qry.Close; DBMain.qry.SQL.Text:= 'update numeros set boletas = '+IntToStr(nComprob+1); DBMain.qry.ExecSQL; except MessageDlg('Error', 'Hay error ', mtWarning, [mbOk], 0); DBMain.fdb.Rollback; end; ..... varias sentencias: inserts, updates.... todas entre try/except DBMain.fdb.Commit; DBMain.fdb.AutoCommit:= true; Si uso un generador para incrementar el contador de comprobantes, se supone que si todo el proceso de grabar est� dentro de la misma transacci�n, puedo seguir consultando por el valor del generador, que no se me va a modificar, no? chauuuuuuuuuu _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

sino me equivoco los generadores estan fuera de las transacciones. usa un contador en tabla para los comprobantes, no te guies de un generador x que este cambia al momento de la consulta.

Twitter: @nenunocomar Maximiliano Duarte Linux User #495070 Ubuntu User #28504 Tolerancia significa disculpar los defectos de los dem�s; tacto, no reparar en ellos. ------------ pr�xima parte ------------ Se ha borrado un adjunto en formato HTML... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus-es/attachments/20100506/3c8db064/attachment.html>

Reply by email

Paola Bruccoleri
to Maxi

Hola Maxi..

Maxi escribi�:

sino me equivoco los generadores estan fuera de las transacciones. usa un contador en tabla para los comprobantes, no te guies de un generador x que este cambia al momento de la consulta.

ok.. o sea, a la manera tradicional :), como lo estoy haciendo ahora.. s�lo quer�a ver de aprovechar esa funcionalidad de firebird, pero tampoco me saca el sue�o no usarla
ahora, respecto al manejo de las transacciones, que opin�s? t� lo haces de esa manera?

chauuuuuuuuuuu

Reply by email

Ismael L. Donis García
to Paola Bruccoleri: Hola.. alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros…

Paola, lo primero que te recomiendo es que pases la l�gica hacia la BD, segundo puedes obtener el valor del generador desde el mismo procedimiento que usas para incrementar el generador y guardarlo en una variable con la cual trabajar�as despu�s.

Te pas� un c�digo de ejemplo que yo uso para que tengas una idea.

SET TERM ^ ;
CREATE PROCEDURE P_NUM_REC (
VCH_ENTIDAD Varchar(7),
SIN_ALMACEN Smallint )
RETURNS (
INT_NREC Integer )
AS
BEGIN
/* Actualiza el n�mero de la recepci�n */
select a.no_r from vtaconteo a where ((a.entidad = :vch_entidad) and (a.almacen = :sin_almacen)) into :int_nrec;
update vtaconteo set no_r = no_r + 1 where ((vtaconteo.entidad = :vch_entidad) and (vtaconteo.almacen = :sin_almacen));

  suspend;

END^
SET TERM ; ^

Saludos
=========
|| ISMAEL ||
=========

Earlier message 42 lines
----- Original Message ----- From: "Paola Bruccoleri" <pbruccoleri en adinet.com.uy> To: "Lista Lazarus" <lazarus-es en lists.lazarus.freepascal.org> Sent: Thursday, May 06, 2010 11:51 AM Subject: [Lazarus-es] zeos-firebird: ejemplo transacciones Hola.. alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros en varias tablas (usando o no sp) y que queden en la misma transacci�n?? quisiera ver c�mo lo est�n resolviendo. esto es lo que yo hago: DBMain.fdb.AutoCommit:= false; try DBMain.qry.Close; DBMain.qry.SQL.Text:= 'update numeros set boletas = '+IntToStr(nComprob+1); DBMain.qry.ExecSQL; except MessageDlg('Error', 'Hay error ', mtWarning, [mbOk], 0); DBMain.fdb.Rollback; end; ..... varias sentencias: inserts, updates.... todas entre try/except DBMain.fdb.Commit; DBMain.fdb.AutoCommit:= true; Si uso un generador para incrementar el contador de comprobantes, se supone que si todo el proceso de grabar est� dentro de la misma transacci�n, puedo seguir consultando por el valor del generador, que no se me va a modificar, no? chauuuuuuuuuu

Reply by email

Claudio Romero
to Paola Bruccoleri: Hola Maxi.. Maxi escribi�: ok.. o sea, a la manera tradicional :), como lo estoy…
Esto es con SQLQuery, aunque con Zeos creo que es bastante parecido.
Sobre usar una transaccion con varios insert, update, un procedimiento
almacenado, aca va un ejemplo, con parambyname o sumando la string del
SQL.
***
    try
    	GrabaCajaBases;
    except
        SQLTransaction3.Rollback;
        raise;
    end;
******
procedure TForm_ManejoCajaBonos.GrabaCajaBases;
	if SQLTransaction3.active then SQLTransaction3.Commit;
	SQLTransaction3.StartTransaction;
	with SQLQuery2 do begin      //aca estan los bonos con ident nomas
		DisableControls;
		First;
		while not SQLQuery2.eof do begin
			consulta:='insert into VTAEXPEN (E,I,F)';
			consulta:=consulta+'VALUES(:E,:IDENT,:FECHA)';
	        SQLQuery3.close;
			SQLQuery3.sql.clear;
	    	SQLQuery3.Sql.add(consulta);
			with SQLQuery3.params do begin
			    ParamByName('E').asstring:='I';
			    ParamByName('I').asstring:=FieldValues['ident'];
			    ParamByName('F').asdate:=fieldbyname('fecha_creacion').AsDateTime;
			end;
			SQLQuery3.ExecSQL;
			//--
			if diagnostico1'' then begin
				SQLQuery3.close;	SQLQuery3.sql.clear;
				SQLQuery3.Sql.add('INSERT INTO
COMENTARIOS_BONO(USUARIO,FECHA_HORA,COMENTARIO,CLAVE_EXPENDIO,COD_USUARIO,ident)
VALUES('+QuotedStr(GnombreDeUsuario)+',current_timestamp,'+QuotedStr('Diag.1:'+diagnostico1)+','+FieldByName('clave_expendio').asstring+','+inttostr(GnroDeUsuario)+','+QuotedStr(FieldByName('ident').asstring)+')');
				SQLQuery3.ExecSQL;
			end;
			//--
			Next;
		end;
	end;
    SQLQuery3.close;
	SQLQuery3.sql.clear;
   	SQLQuery3.Sql.add('EXECUTE PROCEDURE
CIERRA_CAJA_BONOS('+IntToStr(GnroDeUsuario)+','+DBEtoco.text+')');
	SQLQuery3.ExecSQL;
	SQLTransaction3.Commit;//Con esto graba todo
end;

***********
Lo corte de un proyecto, solamente siguelo de ejemplo, pero hay 3 ExecSQL, que se ejecutan todos en la misma transacci�n, si falla algo, falla TODO.

Saludos

Reply by email

José Mejuto
to Claudio Romero

Hello Claudio,

Thursday, May 6, 2010, 9:22:42 PM, you wrote:

CR>                 while not SQLQuery2.eof do begin
CR>                         consulta:='insert into VTAEXPEN (E,I,F)';
CR>
CR> consulta:=consulta+'VALUES(:E,:IDENT,:FECHA)';
CR>                 SQLQuery3.close;
CR>                         SQLQuery3.sql.clear;
CR>                 SQLQuery3.Sql.add(consulta);
CR>                         with SQLQuery3.params do begin
CR>                             ParamByName('E').asstring:='I';
CR> ParamByName('I').asstring:=FieldValues['ident'];
CR> ParamByName('F').asdate:=fieldbyname('fecha_creacion').AsDateTime;
CR>                         end;

Y esto funciona ? Los parametros no son :E, :IDENT y :FECHA ?

Best regards, Jos�

Reply by email

José Antonio Cuello
to Paola Bruccoleri: Hola.. alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros…

Hola, yo trabajo siempre las transacciones manualmente. Simplemente usando la funcion InTransaction de la base de datos o del conection (no recuerdo ahora donde est�) controlas si tienes que hacer el starttransaction, y con try finally o except controlas los rollbacks. Ser�a algo as�:

var vTrans: Boolean;
begin
  vTrans := database.Intransaction;
  try
    if (not vTrans) then database.starttransaction;
    ...
      [sentencias de Insert/Update/Delete]
    ...
    if (not vTrans) then database.commit;
  finally
    if (not vTrans) and database.Intransaction then database.rollback;
  end;
end;

De esta manera si al llamar al proceso has iniciado la transaccion en otro procedimiento usa la transaccion abierta, si no hay transaccion la abre y la cierra.

Espero sea de ayuda.

El jue, 06-05-2010 a las 13:51 -0300, Paola Bruccoleri escribi�:

Show quoted text 39 lines
Hola.. alguien tiene alg�n ejemplo (usando zeos/firebird2) donde graba varios registros en varias tablas (usando o no sp) y que queden en la misma transacci�n?? quisiera ver c�mo lo est�n resolviendo. esto es lo que yo hago: DBMain.fdb.AutoCommit:= false; try DBMain.qry.Close; DBMain.qry.SQL.Text:= 'update numeros set boletas = '+IntToStr(nComprob+1); DBMain.qry.ExecSQL; except MessageDlg('Error', 'Hay error ', mtWarning, [mbOk], 0); DBMain.fdb.Rollback; end; ..... varias sentencias: inserts, updates.... todas entre try/except DBMain.fdb.Commit; DBMain.fdb.AutoCommit:= true; Si uso un generador para incrementar el contador de comprobantes, se supone que si todo el proceso de grabar est� dentro de la misma transacci�n, puedo seguir consultando por el valor del generador, que no se me va a modificar, no? chauuuuuuuuuu _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

________________________________________________________________________

ARTEX TRADING S.A.
Jos� Antonio Cuello Principal

Reply by email

Paola Bruccoleri
to Ismael L. Donis García: Paola, lo primero que te recomiendo es que pases la l�gica hacia la BD, segundo puedes…

Ismael L. Donis Garc�a escribi�:

Show quoted text 24 lines
Paola, lo primero que te recomiendo es que pases la l�gica hacia la BD, segundo puedes obtener el valor del generador desde el mismo procedimiento que usas para incrementar el generador y guardarlo en una variable con la cual trabajar�as despu�s. Te pas� un c�digo de ejemplo que yo uso para que tengas una idea. SET TERM ^ ; CREATE PROCEDURE P_NUM_REC ( VCH_ENTIDAD Varchar(7), SIN_ALMACEN Smallint ) RETURNS ( INT_NREC Integer ) AS BEGIN /* Actualiza el n�mero de la recepci�n */ select a.no_r from vtaconteo a where ((a.entidad = :vch_entidad) and (a.almacen = :sin_almacen)) into :int_nrec; update vtaconteo set no_r = no_r + 1 where ((vtaconteo.entidad = :vch_entidad) and (vtaconteo.almacen = :sin_almacen)); suspend; END^ SET TERM ; ^

Hola Ismael..

como obtengo desde el programa ese numero int_nrec? con el parambyname('init_nrec').asinteger?
chauuuuuuuuuuuu

Reply by email

Ismael L. Donis García
to Paola Bruccoleri
rsbuscar.SQL.Clear;
rsbuscar.SQL.Text := 'execute procedure p_num_rec(:vch_entidad,
:sin_almacen)';
rsbuscar.Params.ParamByName('vch_entidad').AsString:='nombre_de_la_entidad';
rsbuscar.Params.ParamByName('sin_almacen').AsSmallInt:=n�mero_del_almac�n;
trabuscar.StartTransaction;
rsbuscar.Open;
numero_de_la_recepci�n := rsbuscar.FieldByName('int_nrec').AsInteger;

Saludos
=========
|| ISMAEL ||
=========

Earlier message 43 lines
----- Original Message ----- From: "Paola Bruccoleri" <pbruccoleri en adinet.com.uy> To: "Spanish version of Lazarus List" <lazarus-es en lists.lazarus.freepascal.org> Sent: Friday, May 07, 2010 7:12 PM Subject: Re: [Lazarus-es] zeos-firebird: ejemplo transacciones Ismael L. Donis Garc�a escribi�: > Paola, lo primero que te recomiendo es que pases la l�gica hacia la BD, > segundo puedes obtener el valor del generador desde el mismo procedimiento > que usas para incrementar el generador y guardarlo en una variable con la > cual trabajar�as despu�s. > > Te pas� un c�digo de ejemplo que yo uso para que tengas una idea. > > SET TERM ^ ; > CREATE PROCEDURE P_NUM_REC ( > VCH_ENTIDAD Varchar(7), > SIN_ALMACEN Smallint ) > RETURNS ( > INT_NREC Integer ) > AS > BEGIN > /* Actualiza el n�mero de la recepci�n */ > select a.no_r from vtaconteo a where ((a.entidad = :vch_entidad) and > (a.almacen = :sin_almacen)) into :int_nrec; > update vtaconteo set no_r = no_r + 1 where ((vtaconteo.entidad = > :vch_entidad) and (vtaconteo.almacen = :sin_almacen)); > suspend; > END^ > SET TERM ; ^ > Hola Ismael.. como obtengo desde el programa ese numero int_nrec? con el parambyname('init_nrec').asinteger? chauuuuuuuuuuuu

Reply by email

Paola Bruccoleri
to Ismael L. Donis García

Ismael L. Donis Garc�a escribi�:

Show quoted text 10 lines
rsbuscar.SQL.Clear; rsbuscar.SQL.Text := 'execute procedure p_num_rec(:vch_entidad, :sin_almacen)'; rsbuscar.Params.ParamByName('vch_entidad').AsString:='nombre_de_la_entidad'; rsbuscar.Params.ParamByName('sin_almacen').AsSmallInt:=n�mero_del_almac�n; trabuscar.StartTransaction; rsbuscar.Open; numero_de_la_recepci�n := rsbuscar.FieldByName('int_nrec').AsInteger;

Hola!!
agradezco a todos por las ideas que me han dado respecto a este tema... ya casi casi tengo todo funcionando... ver� esta tarde de seguir en esto!! chauuuuuuuuuuu

Reply by email

Paola Bruccoleri
to José Antonio Cuello: Hola, yo trabajo siempre las transacciones manualmente. Simplemente usando la funcion…

Jos� Antonio Cuello escribi�:

Show quoted text 21 lines
Hola, yo trabajo siempre las transacciones manualmente. Simplemente usando la funcion InTransaction de la base de datos o del conection (no recuerdo ahora donde est�) controlas si tienes que hacer el starttransaction, y con try finally o except controlas los rollbacks. Ser�a algo as�: var vTrans: Boolean; begin vTrans := database.Intransaction; try if (not vTrans) then database.starttransaction; ... [sentencias de Insert/Update/Delete] ... if (not vTrans) then database.commit; finally if (not vTrans) and database.Intransaction then database.rollback; end; end;

Hola Jos�..
segu� tu esquema para agrupar las sentencias sql en una misma transacci�n, y hoy estuve haciendo pruebas y no me est� funcionando. No se si soy yo o un problema del zeos.
(zeos7.0.0, firebird 2.1.3).

   vTrans := DBMain.fdb.Intransaction;
   try
      if (not vTrans) then DBMain.fdb.StartTransaction;
      Graba;
      if (not vTrans) then DBMain.fdb.Commit;
   finally
      if (not vTrans) and DBMain.fdb.Intransaction then DBMain.fdb.Rollback;
      MessageDlg('Error', 'Hay error en los datos', mtWarning, [mbOk], 0);
   end;

Graba() hace esto:
DBMain.fdb.AutoCommit:= false;
ejecuta un store procedure
ejecuta varios inserts en tabla A
ejecuta un delete en tabla B

A prop�sito mando datos err�neos en el delete, violando la integridad referencial o poniendo mal un nombre de par�metro y al chequear la bd, veo que se ejecut� y "commiteo" la store procedure y los inserts... Por tanto, no me quedan las 3 sentencias agrupadas en la MISMA transacci�n.

qu� estar� pasando?
muchas gracias a todos..
chauuuuuuuuuu

Reply by email

José Antonio Cuello
to Paola Bruccoleri

El mi�, 12-05-2010 a las 21:34 -0300, Paola Bruccoleri escribi�:

Show quoted text 14 lines
Hola Jos�.. segu� tu esquema para agrupar las sentencias sql en una misma transacci�n, y hoy estuve haciendo pruebas y no me est� funcionando. No se si soy yo o un problema del zeos. (zeos7.0.0, firebird 2.1.3). vTrans := DBMain.fdb.Intransaction; try if (not vTrans) then DBMain.fdb.StartTransaction; Graba; if (not vTrans) then DBMain.fdb.Commit; finally if (not vTrans) and DBMain.fdb.Intransaction then

Aqu� te faltar�a un begin / end que agrupe el rollback y el messageDlg

Show quoted text 23 lines
DBMain.fdb.Rollback; MessageDlg('Error', 'Hay error en los datos', mtWarning, [mbOk], 0); end; Graba() hace esto: DBMain.fdb.AutoCommit:= false; ejecuta un store procedure ejecuta varios inserts en tabla A ejecuta un delete en tabla B A prop�sito mando datos err�neos en el delete, violando la integridad referencial o poniendo mal un nombre de par�metro y al chequear la bd, veo que se ejecut� y "commiteo" la store procedure y los inserts... Por tanto, no me quedan las 3 sentencias agrupadas en la MISMA transacci�n. qu� estar� pasando? muchas gracias a todos.. chauuuuuuuuuu

Si te est� haciendo el commit es porque el procedimiento/funcion graba no devuelve error alguno. No s� si ser� por el storeprocedure del Zeos al lanzar el delete, porque al llegar al procedimiento la base de datos ya est� en transacci�n y el procedimiento anterior no gestiona la transaccion o por que te est� abriendo distintas transacciones.

De todas maneras yo no cambio DBMain.fdb.AutoCommit:= false; Siempre lo
dejo en True y nunca me ha dado problema.

Yo inicialmente probar�a a cambiar el procedimiento de delete por un TZQuery con un SQL tipo "DELETE FROM" para eliminar variables. Tambi�n si queres pasame un ejemplo para poder hecharle un vistazo haber si consigo ver algo. Ya sabes, cuatro ojos ven m�s que dos .... :)

Un saludo.

________________________________________________________________________

ARTEX TRADING S.A.
Jos� Antonio Cuello Principal

Reply by email

Paola Bruccoleri
to José Antonio Cuello

Jos� Antonio Cuello escribi�:

Show quoted text 14 lines
Si te est� haciendo el commit es porque el procedimiento/funcion graba no devuelve error alguno. No s� si ser� por el storeprocedure del Zeos al lanzar el delete, porque al llegar al procedimiento la base de datos ya est� en transacci�n y el procedimiento anterior no gestiona la transaccion o por que te est� abriendo distintas transacciones. De todas maneras yo no cambio DBMain.fdb.AutoCommit:= false; Siempre lo dejo en True y nunca me ha dado problema. Yo inicialmente probar�a a cambiar el procedimiento de delete por un TZQuery con un SQL tipo "DELETE FROM" para eliminar variables. Tambi�n si queres pasame un ejemplo para poder hecharle un vistazo haber si consigo ver algo. Ya sabes, cuatro ojos ven m�s que dos .... :)

Hola Jos�...
es que solo ejecuto un store procedure usando un tzquery, el insert y el delete son tzquerys comunes (no invocan ningun sp). Voy a ver de armar un peque�o programa de ejemplo as� te lo env�o para probar...
muchas gracias!!!
chauuuuuuuuuuuu

Reply by email

Paola Bruccoleri
to José Antonio Cuello: El mi�, 12-05-2010 a las 21:34 -0300, Paola Bruccoleri escribi�: Aqu� te faltar�a…

Jos� Antonio Cuello escribi�:

Show quoted text 17 lines
Si te est� haciendo el commit es porque el procedimiento/funcion graba no devuelve error alguno. No s� si ser� por el storeprocedure del Zeos al lanzar el delete, porque al llegar al procedimiento la base de datos ya est� en transacci�n y el procedimiento anterior no gestiona la transaccion o por que te est� abriendo distintas transacciones. De todas maneras yo no cambio DBMain.fdb.AutoCommit:= false; Siempre lo dejo en True y nunca me ha dado problema. Yo inicialmente probar�a a cambiar el procedimiento de delete por un TZQuery con un SQL tipo "DELETE FROM" para eliminar variables. Tambi�n si queres pasame un ejemplo para poder hecharle un vistazo haber si consigo ver algo. Ya sabes, cuatro ojos ven m�s que dos .... :)

Estoy haciendo un proyecto con las mismas querys y dem�s yerbas, y me est� funcionando como corresponde..:)
no entiendo nada..... o creo que si..
en este proyecto simplito, solo tengo un form donde no pido ning�n dato ni nada, solo grabo, por tanto, no hay transacciones abiertas de nada, porque no se muestran datos en grids ni nada por el estilo. En el proyecto real, tengo un form donde muestro datos, y al grabar, pido anteriormente otros que saco de otras tablas, etc...!!

O sea, se ve que hay una transacci�n "abierta", y como el autocommit es true, se va "commiteando" todo lo que se hace...

supongo que deber� hacer un commit antes del start transaction, no?? ver� de seguir haciendo pruebas dentro de un rato xq ya me voy... chauuuuuuuuuuuuu

Reply by email

José Mejuto
to Paola Bruccoleri

Hello Paola,

Thursday, May 13, 2010, 7:18:23 PM, you wrote:

PB> supongo que deber� hacer un commit antes del start transaction, no?? PB> ver� de seguir haciendo pruebas dentro de un rato xq ya me voy... PB> chauuuuuuuuuuuuu

La mayor parte de BBDD modernas el "starttransaction" es impl�cito, esto es, tan pronto intentas grabar also se inicia una transacci�n, quieras o no, que debe de finalizar con un commit/rollback.

Lo que te puede pasar es que tengas un rollback por alg�n sitio. Un starttransaction sin un commit/rollback previo puede provocar un rollback impl�cito, al igual que se asume si se cierra una conexi�n.

En las SP tendemos a poner commits al final, y olvidarnos de que lo hemos puesto, y las transacciones no son solapables ;)

Best regards, Jos�

Reply by email

Maxi
to José Mejuto

El d�a 13 de mayo de 2010 14:41, Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 29 lines
Hello Paola, Thursday, May 13, 2010, 7:18:23 PM, you wrote: PB> supongo que deber� hacer un commit antes del start transaction, no?? PB> ver� de seguir haciendo pruebas dentro de un rato xq ya me voy... PB> chauuuuuuuuuuuuu La mayor parte de BBDD modernas el "starttransaction" es impl�cito, esto es, tan pronto intentas grabar also se inicia una transacci�n, quieras o no, que debe de finalizar con un commit/rollback. Lo que te puede pasar es que tengas un rollback por alg�n sitio. Un starttransaction sin un commit/rollback previo puede provocar un rollback impl�cito, al igual que se asume si se cierra una conexi�n. En las SP tendemos a poner commits al final, y olvidarnos de que lo hemos puesto, y las transacciones no son solapables ;) -- Best regards, �Jos� _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

primero tenes que commitear antes de la nueva transaccion, sino la continua a la anterior.

Twitter: @nenunocomar Maximiliano Duarte Linux User #495070 Ubuntu User #28504 El que pregunta aprende, y el que contesta aprende a responder.

Reply by email

José Mejuto
to Maxi

Hello Maxi,

Thursday, May 13, 2010, 8:48:30 PM, you wrote:

M> primero tenes que commitear antes de la nueva transaccion, sino la M> continua a la anterior.

Pues eso es lo que he puesto, no ?

Best regards, Jos�

Reply by email

José Antonio Cuello
to Paola Bruccoleri: Jos� Antonio Cuello escribi�: Hola Jos�... es que solo ejecuto un store procedure…

Es que existe un componente para ejecutar procedimientos. En su d�a lo us� y funcionaba muy bien.

El jue, 13-05-2010 a las 13:18 -0300, Paola Bruccoleri escribi�:

Show quoted text 9 lines
Hola Jos�... es que solo ejecuto un store procedure usando un tzquery, el insert y el delete son tzquerys comunes (no invocan ningun sp). Voy a ver de armar un peque�o programa de ejemplo as� te lo env�o para probar... muchas gracias!!! chauuuuuuuuuuuu

________________________________________________________________________

ARTEX TRADING S.A.
Jos� Antonio Cuello Principal

Reply by email

Paola Bruccoleri
to José Antonio Cuello

Jos� Antonio Cuello escribi�:

Es que existe un componente para ejecutar procedimientos. En su d�a lo us� y funcionaba muy bien.

Hola Jos�... si, justamente ese mismo componente ahora no funciona bien.. ya lo report� en el foro de zeos y envi� un programita reproduciendo el problema.
todav�a sigo sin resolver nada....
ver� de seguir un poco esta tarde...
chauuuuuuuu

Reply by email

Paola Bruccoleri
to José Antonio Cuello: El mi�, 12-05-2010 a las 21:34 -0300, Paola Bruccoleri escribi�: Aqu� te faltar�a…

Jos� Antonio Cuello escribi�:

Show quoted text 18 lines
El mi�, 12-05-2010 a las 21:34 -0300, Paola Bruccoleri escribi�: > Hola Jos�.. > segu� tu esquema para agrupar las sentencias sql en una misma > transacci�n, y hoy estuve haciendo pruebas y no me est� funcionando. > No > se si soy yo o un problema del zeos. > (zeos7.0.0, firebird 2.1.3). > > vTrans := DBMain.fdb.Intransaction; > try > if (not vTrans) then DBMain.fdb.StartTransaction; > Graba; > if (not vTrans) then DBMain.fdb.Commit; > finally > if (not vTrans) and DBMain.fdb.Intransaction then >

Hola Jos�..
cambi� finally por except y ahora "aparentemente" est� funcionando bien.. o sea, si hay error, no ejecuta ninguna sentencia sql. De todas maneras, seguir� provocando errores en otros lados a ver que pasa...
muchas gracias a todos..
chauuuuuuuuuuuu

Reply by email

José Mejuto
to Paola Bruccoleri

Hello Paola,

you wrote 8 lines
>> vTrans := DBMain.fdb.Intransaction; >> try >> if (not vTrans) then DBMain.fdb.StartTransaction; >> Graba; >> if (not vTrans) then DBMain.fdb.Commit; >> finally >> if (not vTrans) and DBMain.fdb.Intransaction then >>

PB> Hola Jos�..
PB> cambi� finally por except y ahora "aparentemente" est� funcionando PB> bien.. o sea, si hay error, no ejecuta ninguna sentencia sql. PB> De todas maneras, seguir� provocando errores en otros lados a ver que PB> pasa...
PB> muchas gracias a todos..
PB> chauuuuuuuuuuuu

No se como haceis el tema este, pero lo l�gico ser�a:

[...]
try
  SQL.Execute; //Lo que sea, insert, sp, delete...
except
  SQL.RollBack;
  Exit;
end;
try
  SQL.Execute;
except
  SQL.RollBack;
  Exit;
end;
SQL.Commit;
[...]

Si todo est� en una funci�n, reemplazar los:

SQL.RollBack por false.
SQL.Commit por true.

Best regards, Jos�

Reply by email

Paola Bruccoleri
to José Mejuto

Jos� Mejuto escribi�:

Show quoted text 24 lines
No se como haceis el tema este, pero lo l�gico ser�a: [...] try SQL.Execute; //Lo que sea, insert, sp, delete... except SQL.RollBack; Exit; end; try SQL.Execute; except SQL.RollBack; Exit; end; SQL.Commit; [...] Si todo est� en una funci�n, reemplazar los: SQL.RollBack por false. SQL.Commit por true.

Hola Jos�..
en un principio, m�s o menos ten�a esa estructura.. luego agrup� todas las sentencias en un procedimiento y ah� fue el l�o. Dentro de ese procedimiento, las sentencias no est�n dentro del try/except.. est�n unas a continuaci�n de otras. Quiz�s, esa no es la forma m�s correcta de hacerlo...

Seg�n tu ejemplo, entonces si agrupo todo ser�a algo as�.??

try
  grabar();
  connection.commit
except
 connection.rollback;
function grabar(): boolean
try
  SQL.Execute; //Lo que sea, insert, sp, delete...
except
  result:= false;
  Exit;
end;
try
  SQL.Execute;
except
  result:= false;
  Exit;
end;
result:= true;

Reply by email

José Mejuto
to Paola Bruccoleri

Hello Paola,

Friday, May 14, 2010, 8:36:08 PM, you wrote:

PB> en un principio, m�s o menos ten�a esa estructura.. luego agrup� todas PB> las sentencias en un procedimiento y ah� fue el l�o. PB> Dentro de ese procedimiento, las sentencias no est�n dentro del PB> try/except.. est�n unas a continuaci�n de otras. PB> Quiz�s, esa no es la forma m�s correcta de hacerlo... PB> Seg�n tu ejemplo, entonces si agrupo todo ser�a algo as�.??

Hmmm, parecido, ya que al ser una funci�n tienes dos opciones para hacerlo, usando try..except impl�cito para cada execute, o dejando que las excepciones en grupo funcionen. Puedes hacerlo de estos dos modos:

if grabar() then begin
  connection.commit
end else begin
  connection.rollback;
end;
function grabar(): boolean
begin
try
  SQL.Execute; //Lo que sea, insert, sp, delete...
except
  result:= false;
  Exit;
end;
try
  SQL.Execute;
except
 result:= false;
 Exit;
end;
result:= true;
end;

Tiene la "ventaja" de que puedes reaccionar diferente a cada excepci�n si fuera necesario, o bien:

try
  grabar()
  connection.commit;
except
  connection.rollback;
end;
procedure grabar();
begin
  SQL.Execute; //Lo que sea, insert, sp, delete...
  SQL.Execute;
  [...]
  SQL.Execute;
end;

Si cualquiera de las 3 execute dispara una excepci�n se ejecuta el bloque except sin pasar por la linea de commit, con el consiguiente rollback del grupo except.

El "truco" est� en usar el mismo sistema en todos los grupos de actuaciones. Muchas veces necesitamos hacer un insert de muuuuchos registros, esto ralentiza todo si est� en una transacci�n, por lo tanto a veces hay que armarse de paciencia para buscar la combinaci�n de �rdenes de insert para maximizar la velocidad sin comprometer la estructura de los datos.

Un ejemplo, supongamos que queremos crear un hist�rico, pero este hist�rico puede tener millones de registros. Si los metemos todos en una trasacci�n, esto llevar� horas, mientras que si hacemos un commit cada 10000 registros, lo podemos meter en la base de datos en 10 minutos. En este caso tenemos que vendernos al control manual de las transacciones y usar alg�n truco para saber todo lo que hemos metido por si se necesita borrar. Si la BBDD la dise�amos nosotros a�adimos un campo "Verificado" como GUID, lo que nos servir� de control de la transacci�n y har�amos algo como:

var
 j: integer;
 MyTrans: TGUID;
begin
 MyTrans:=GUIDCreate();
 j:=0
 while not DatosEntrada.EOF do begin
   SQL.FieldByName('GUID').asLoQueSea:=MyTrans;
   SQL.FieldByName('Otro').asInteger=DatosEntrada.Loquesea;
   try
     SQL.Insert;
     if j>10000 then begin
       SQL.Commit;
       j:=0;
     end;
   except
     SQL.Rollback;
     SQL.SQL.Text:='DELETE FROM HISTORICO WHERE GUID='+MyTrans;
     try
       SQL.Execute;
       SQL.Commit;
     except
       MessageBox('Algo muy malo ha pasado');
       //Guardamos el GUID en un fichero local, para hacer un borrado
       //m�s tarde, cuando se sepa por que no ha funcionado la
       //excepci�n.
     end;
   end;
 end;
end;

La contrapartida de esto es que tenemos que acordarnos de que todos los SQL que consulten el hist�rico han de disponer de un "AND GUID is NULL" en el where o donde corresponda.

Best regards, Jos�

Reply by email

Paola Bruccoleri
to José Mejuto

Jos� Mejuto escribi�:

Show quoted text 5 lines
Hmmm, parecido, ya que al ser una funci�n tienes dos opciones para hacerlo, usando try..except impl�cito para cada execute, o dejando que las excepciones en grupo funcionen. Puedes hacerlo de estos dos modos:

espectacular las explicaciones!!! un verdadero profesor!!! :) las guardar� para tener en cuenta... tienes mucha raz�n respecto a la carga de muchos registros...
muchas gracias!!!
chauuuuuuuuuuu

Reply by email

José Antonio Cuello
to José Mejuto: PB> en un principio, m�s o menos ten�a esa estructura.. luego agrup� todas PB> las…

Buen ejemplo de grabaci�n masiva. Por otro lado s�lo indicar que yo uso normalmente try/finally en vez de try/except por comodidad m�a, ya que suelo usar muchos objetos/clases y as� pongo un solo free, en el finally. Est� claro que en el finally tienes que controlar si se ha hecho el commit ya que siempre pasar� por el finally, con o sin error.

Un saludo.

El vie, 14-05-2010 a las 21:26 +0200, Jos� Mejuto escribi�:

Hmmm, parecido, ya que al ser una funci�n tienes dos opciones para hacerlo, usando try..except impl�cito para cada execute, o dejando que las excepciones en grupo funcionen. Puedes hacerlo de estos dos modos:

________________________________________________________________________

ARTEX TRADING S.A.
Jos� Antonio Cuello Principal

Reply by email