[firebase-br] [OFF] Select dentro de uma transação utilizando o drive UIB está influenciando no rollback.

Eduardo Pombo eduardo em embras.net
Seg Ago 16 15:29:38 -03 2010


ja neste ultimo exemplo a transacao esta fora do laco e com isso a 2a
e 3a volta estao sem transacao. acredito que teria q colocar o start
da transacao dentro do laco



Em 16 de agosto de 2010 11:54, Junior Miranda <jrmiran em gmail.com> escreveu:
> Observem este código de um exemplo simples:
>
> var
> T_ID1: TTransactionDesc;
> begin
>  //-
>  T_ID1.TransactionID  := 1;
>  T_ID1.IsolationLevel := xilREADCOMMITTED;
>  SQLConnection1.StartTransaction(T_ID1);
>
>  //-
>  ClientDataSet1.Open;
>  ClientDataSet1.First;
>  //-
>  try
>   while not (ClientDataSet1.Eof) do
>     begin
>       //-
>       SqlQuery1.Close;
>       SqlQuery1.Sql.Text := 'SELECT CAB_NUM FROM CABECALHO WHERE CAB_ID = '
> + QuotedStr(IntToStr(ClientDataSet1IT_FKCAB_ID.AsInteger));
>       SqlQuery1.open;
>
>       //-
>       SQLQuery2.Close;
>       SQLQuery2.SQL.Text := 'UPDATE ITENS SET IT_NUM =' +
> QuotedStr(IntToStr(SqlQuery1.Fields.Fields[0].AsInteger + 1)) +  ' WHERE
> IT_FKCAB_ID =' + QuotedStr(IntToStr(ClientDataSet1IT_FKCAB_ID.AsInteger));
>       SQLQuery2.ExecSQL();
>
>       //-
>       SQLQuery3.Close;
>       SQLQuery3.SQL.Text := 'UPDATE CABECALHO SET CAB_NUM =' +
> QuotedStr(IntToStr(SqlQuery1.Fields.Fields[0].AsInteger + 1)) +  ' WHERE
> CAB_ID =' + QuotedStr(IntToStr(ClientDataSet1IT_FKCAB_ID.AsInteger));
>       SQLQuery3.ExecSQL();
>
>       //-
>       ClientDataSet1.Next;
>     end;
>  Raise Exception.Create('');
>  SQLConnection1.Commit(T_ID1);
>  except
>   SQLConnection1.Rollback(T_ID1);
>  end;
>
> O raise que estou utilizando para simular uma excessão, nos levará ao
> rollback. Mas digamos que 3 registros tenham sido alterados. O rollback não
> alcança o dois primeiros.
> Explico:
> O select executado na segunda volta do laço, comitta os ExecSql
> anteriores(Executados na primeira volta). O select executado na terceira
> volta do laço, comitta os ExecSql anteriores(Executados na segunda volta).
> Já na última volta, como chegamos ao final do laço, não ocorrerá um novo
> select. Com o raise, vamos ao except. Só que na verdade só existe um
> registro pendente (O último). Os dois primeiro foram commitados pela
> execussão do select. O select commita mas mantém a transação aberta. Com
> drive Interbase por exemplo, funciona normal! Ou seja, ao final, com  o
> raise, o rollback ocorrerá sobre todos os registro mencionados.
>
> []'s
>
> Júnior Miranda.
> --------------------------------------------------
> From: "Eduardo Pombo" <eduardo em embras.net>
> Sent: Monday, August 16, 2010 10:53 AM
> To: "FireBase" <lista em firebase.com.br>
> Subject: Re: [firebase-br][OFF] Select dentro de uma transação utilizando o
> drive UIB está influenciando no rollback.
>
>> Acredito que o problema seja pq no momento que o erro ocorre a
>> transacao ainda nao esteja criada.
>> ex: se o erro ocorrer neste item abaixo a transacao ainda nao foi
>> criada e ai vai para o except e com isso o rollback nao vai funcionar
>> por nao ter transacao criada.
>>
>>      ClientDataSet1.Edit;
>>      ClientDataSet1IT_NUM.AsInteger  :=
>> SqlQuery2.Fields.Fields[0].AsInteger;
>>      ClientDataSet1.Post;
>>
>> sugestao, mova o bloco abaixo para antes dos post e execsql.
>>
>> //-
>> T_ID1.TransactionID  := 1;
>> T_ID1.IsolationLevel := xilREADCOMMITTED;
>> SQLConnection1.StartTransaction(T_ID1);
>> //-
>>
>>
>>
>> Abraco,
>>
>> Espero ter ajudado
>>
>> Em 16 de agosto de 2010 09:03, Junior Miranda <jrmiran em gmail.com>
>> escreveu:
>>>
>>> Senhores, bom dia!
>>>
>>> Desculpem-me pela natureza OFF do post. Mas, é que já rodei por todos os
>>> lados e não encontrei nenhuma solução que não seja substituir o drive UIB.
>>> Mas infelizmente não posso fazer esta substituição neste momento. O
>>> problema é que como o select está dentro da transação e em loop, a cada
>>> volta,
>>> ele (o select), commita o(s) ExecSql anterior(es). Isto antes do commit
>>> propriamente dito. Então, quando há uma excessão, o rollback não funciona
>>> como devido.
>>> Quero garantir a atomicidade. Mas o bendito drive UIB não permite(Sob
>>> esta condição). Como não posso mudar o drive no momento, preciso encontrar
>>> uma
>>> alternativa(na aplicação). Mas até agora nada funcionou.
>>>
>>> O código é este:
>>> //------------
>>> var
>>> T_ID1: TTransactionDesc;
>>> begin
>>>  //-
>>>  ClientDataSet1.Open;
>>>  ClientDataSet1.First;
>>>  //-
>>>  try
>>>   while not (ClientDataSet1.Eof) do
>>>     begin
>>>       //-
>>>       SqlQuery2.Close;
>>>       SqlQuery2.Sql.Text := 'SELECT CAB_NUM FROM CABECALHO WHERE CAB_ID =
>>> ' + QuotedStr(IntToStr(ClientDataSet1IT_FKCAB_ID.AsInteger));
>>>       SqlQuery2.open;
>>>
>>>       ClientDataSet1.Edit;
>>>       ClientDataSet1IT_NUM.AsInteger  :=
>>> SqlQuery2.Fields.Fields[0].AsInteger;
>>>       ClientDataSet1.Post;
>>>
>>>       //-
>>>       SQLQuery1.Close;
>>>       SQLQuery1.SQL.Text := 'UPDATE CABECALHO SET CAB_NUM =' +
>>> QuotedStr(IntToStr(SqlQuery2.Fields.Fields[0].AsInteger + 1)) +  ' WHERE
>>> CAB_ID =' + QuotedStr(IntToStr(ClientDataSet1IT_FKCAB_ID.AsInteger));
>>>       SQLQuery1.ExecSQL();
>>>
>>>       //-
>>>       ClientDataSet1.Next;
>>>     end;
>>>  //-
>>>  T_ID1.TransactionID  := 1;
>>>  T_ID1.IsolationLevel := xilREADCOMMITTED;
>>>  SQLConnection1.StartTransaction(T_ID1);
>>>  //-
>>>  if ClientDataSet1.ApplyUpdates(0) <> 0 then
>>>   Raise Exception.Create('');
>>>  //-
>>>  SQLConnection1.Commit(T_ID1);
>>>  except
>>>   SQLConnection1.Rollback(T_ID1);
>>>  end;
>>> //-------
>>> Onde há o objeto ClientDataset1, eu também já utilizei um terceiro
>>> TSqlQuery para fazer um update(Ou seja, só com objetos TSqlQuery). Alguém já
>>> passou por isso e conseguiu contornar a questão do select dentro de um laço
>>> em uma transação com Drive UIB?
>>>
>>> []'s
>>> ______________________________________________
>>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
>>> Para saber como gerenciar/excluir seu cadastro na lista, use:
>>> http://www.firebase.com.br/fb/artigo.php?id=1107
>>> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>>>
>>
>>
>>
>> --
>>
>> Atenciosamente
>>
>> José Eduardo Pombo de Barros
>> Gerente de Manutenção de Sistemas
>>
>> ______________________________________________
>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
>> Para saber como gerenciar/excluir seu cadastro na lista, use:
>> http://www.firebase.com.br/fb/artigo.php?id=1107
>> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>



-- 

Atenciosamente

José Eduardo Pombo de Barros
Gerente de Manutenção de Sistemas




Mais detalhes sobre a lista de discussão lista