Commit X Rollback
[u:af77a16a4b]Situação:[/u:af77a16a4b]
Numa determinada operação, possuo 8 instruções sql para serem executadas no banco, uma a uma, com tabelas diferentes, em qq uma delas q resultar um erro, devo desfazer todas.
[u:af77a16a4b]Ocorrencia:[/u:af77a16a4b]
Tenho 3 instruções inserts e 5 updates, executo todas, porem uma a uma com um SQLQuery, inserindo a instrução e efetuando um ExecSql.
[u:af77a16a4b]Exemplo: [/u:af77a16a4b]
****************************************
qTmp := TSQLQuery.Create(nil);
qTmp.SQLConnection := DMPrincipal.sql_conn;
with qTmp do begin
Close;
Sql.Clear;
Sql.Add(´update tb_tabela set compo=:par where codigo=:cod´);
ParamByName(´par´).DataType := ftInteger;
ParamByName(´cod´).DataType := ftInteger;
ParamByName(´par´).AsInteger := valor1;
ParamByName(´cod´).AsInteger := valor2;
try
ExecSQL();
except
on E: Exception do begin
MessageDlg(E.Message, mterror, [mbok],0);
// desfazendo toda a transação
DMPrincipal.sql_conn.Rollback(TransDesc);
abort;
end;
end;
Close;
Free;
end;
******************
assim sucessivamente com todas as 8 instruções, seja de insert ou de update.
[u:af77a16a4b]Problema:[/u:af77a16a4b]
Antes da 1ª instrução, eu abro uma transação, e depois da ultima eu fecho com o commit, até aí td bem, ele executa perfeitamente, mas ao inves de fechar com um commit, resolvi colocar um rollback pra testar se ele iria desfazer todas as 8, e algo me incomodou, na primeira instrução INSERT q ele executa, dali pra baixo no codigo ele desfaz, os anteriores ao INSERT não, por exemplo, havia deixado na sequencia todos os updates depois os inserts, e no final dava o rollback, na teoria teria q desfazer td, porem os 5 updates e o 1º insert ele nao desfaz, aí troquei, coloquei primeiro os inserts e depois os updates, aí ele nao desfaz o 1º insert, o restante, desfez td, ai inverti a posição dos inserts, pois tenho 3, e qq um deles q eu colocar em 1º no codigo, esse ele nao desfaz, não consegui entender a razão.
Uso Delphi 7 e firebird 1.5 e DBExpress, se alguém puder me ajudar, agradeço.
Numa determinada operação, possuo 8 instruções sql para serem executadas no banco, uma a uma, com tabelas diferentes, em qq uma delas q resultar um erro, devo desfazer todas.
[u:af77a16a4b]Ocorrencia:[/u:af77a16a4b]
Tenho 3 instruções inserts e 5 updates, executo todas, porem uma a uma com um SQLQuery, inserindo a instrução e efetuando um ExecSql.
[u:af77a16a4b]Exemplo: [/u:af77a16a4b]
****************************************
qTmp := TSQLQuery.Create(nil);
qTmp.SQLConnection := DMPrincipal.sql_conn;
with qTmp do begin
Close;
Sql.Clear;
Sql.Add(´update tb_tabela set compo=:par where codigo=:cod´);
ParamByName(´par´).DataType := ftInteger;
ParamByName(´cod´).DataType := ftInteger;
ParamByName(´par´).AsInteger := valor1;
ParamByName(´cod´).AsInteger := valor2;
try
ExecSQL();
except
on E: Exception do begin
MessageDlg(E.Message, mterror, [mbok],0);
// desfazendo toda a transação
DMPrincipal.sql_conn.Rollback(TransDesc);
abort;
end;
end;
Close;
Free;
end;
******************
assim sucessivamente com todas as 8 instruções, seja de insert ou de update.
[u:af77a16a4b]Problema:[/u:af77a16a4b]
Antes da 1ª instrução, eu abro uma transação, e depois da ultima eu fecho com o commit, até aí td bem, ele executa perfeitamente, mas ao inves de fechar com um commit, resolvi colocar um rollback pra testar se ele iria desfazer todas as 8, e algo me incomodou, na primeira instrução INSERT q ele executa, dali pra baixo no codigo ele desfaz, os anteriores ao INSERT não, por exemplo, havia deixado na sequencia todos os updates depois os inserts, e no final dava o rollback, na teoria teria q desfazer td, porem os 5 updates e o 1º insert ele nao desfaz, aí troquei, coloquei primeiro os inserts e depois os updates, aí ele nao desfaz o 1º insert, o restante, desfez td, ai inverti a posição dos inserts, pois tenho 3, e qq um deles q eu colocar em 1º no codigo, esse ele nao desfaz, não consegui entender a razão.
Uso Delphi 7 e firebird 1.5 e DBExpress, se alguém puder me ajudar, agradeço.
Rocetti
Curtidas 0
Respostas
Motta
26/10/2006
Deveria desfazer tudo.
Alguma tabela dispara trigger ou stored procedure e nesta tem um commit solto ?
Alguma tabela dispara trigger ou stored procedure e nesta tem um commit solto ?
GOSTEI 0
Tnaires
26/10/2006
Olá
Pra evitar isso, você deve iniciar a transação explicitamente chamando um StartTransaction antes de executar a primeira instrução. Assim, o Rollback voltará para esse ponto, independentemente de outras instruções serem ´acidentalmente´ executadas via trigger.
Abraços
Pra evitar isso, você deve iniciar a transação explicitamente chamando um StartTransaction antes de executar a primeira instrução. Assim, o Rollback voltará para esse ponto, independentemente de outras instruções serem ´acidentalmente´ executadas via trigger.
Abraços
GOSTEI 0
Motta
26/10/2006
Só aventei a hipotese de alguma instrução COMMIT perdida em algum ponto, o rollback defaz inclusive as instruções disparadas por triggers, claro.
GOSTEI 0
Rocetti
26/10/2006
Antes da 1ª instrução eu abro a transação:
TransDesc.TransactionID := transact;
TransDesc.IsolationLevel := xilREADCOMMITTED;
DMPrincipal.sql_conn.StartTransaction(TransDesc);
e no final de todas as instruções fecho a transação, pois é um bloco só, ou é tudo ou é nada.
Agora sobre disparar triggers, vou ver aki.
TransDesc.TransactionID := transact;
TransDesc.IsolationLevel := xilREADCOMMITTED;
DMPrincipal.sql_conn.StartTransaction(TransDesc);
e no final de todas as instruções fecho a transação, pois é um bloco só, ou é tudo ou é nada.
Agora sobre disparar triggers, vou ver aki.
GOSTEI 0
Rocetti
26/10/2006
Realmente possuo um trigger na 1ª instrução, a de autoincremento.
CREATE TRIGGER TRG_INS_NF FOR TB_NF
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.nf_controle is null) then
new.nf_controle = gen_id(gen_nf, 1);
end
mas essa trigger executa o commit sozinha ????
CREATE TRIGGER TRG_INS_NF FOR TB_NF
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.nf_controle is null) then
new.nf_controle = gen_id(gen_nf, 1);
end
mas essa trigger executa o commit sozinha ????
GOSTEI 0
Tnaires
26/10/2006
Essa trigger não executa o commit sozinha. O que acontece é que o valor do generator não é recuperado quando um Rollback é efetuado.
GOSTEI 0
Rocetti
26/10/2006
Ok caro Tarso, isso quer dizer que a trigger nao esta interferindo em nada, ou seja, ele executa, mas o rollback desfaz sem problemas. O q pode estar acontecendo intaum ???
GOSTEI 0