Fórum Consulta influenciando na transação #383578
13/08/2010
0
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 //- ESTE É O SELECT <========== 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; //- if ClientDataSet1.ApplyUpdates(0) = 0 then SQLConnection1.Commit(T_ID1) else SQLConnection1.Rollback(T_ID1) except SQLConnection1.Rollback(T_ID1); end;
Sem o select, o rollback funciona. Alguém já passou por esta experiência?? Como manter o select e ele não influenciar no rollback?
Continuo pesquisando. Caso encontre uma reposta posto. Mas se alguem puder contribuir...
Uso Firebird 2.0 com Drive UIB
[]'s
Junior Miranda
Curtir tópico
+ 0Posts
13/08/2010
Marcos Iwazaki
Qdo vc diz que o select influencia, em que sentido esta influenciando?
Gostei + 0
13/08/2010
Junior Miranda
Qdo vc diz que o select influencia, em que sentido esta influenciando?
Obrigado pela atenção! No exemplo que postei, são alterados os valores em duas tabelas. O select recupera o valor da tabela CABECALHO e atribui a tabela ITENS(ClientDataset1). O update incrementa o valor da tabela CABECALHO. O problema é que com a presença do select, se for levantada uma excessão, apenas a tabela de ITENS sofre o rollback. A tabela CABECALHO é alterada. Se retiro o select e simulo... o rollback funciona!
[]'s
Gostei + 0
13/08/2010
Marcos Iwazaki
Mas uma coisa que pode causar problema ae é o ClientDataSet.
Pois qdo vc faz operações nele, ele guarda os valores em memoria, mesmo depois de ter feito rollback o dados alterados ainda estão em memoria. Isso quer dizer se for fazer rollback vc tem q cancelar o clientDataSet tbm.
Veja se isso resolve.
Gostei + 0
13/08/2010
Junior Miranda
[]'s
Gostei + 0
13/08/2010
Junior Miranda
Amigo socram, responda novamente esta thread para finalizarmos e vc ficar o crédito pela atenção dada.
[]'s
Gostei + 0
13/08/2010
Junior Miranda
Amigo socram, responda novamente esta thread para finalizarmos e vc ficar o crédito pela atenção dada.
[]'s
Durante os estudos, encontrei várias citações para este problema(Nenhuma solução mantendo o drive). Segundo estas citações, a questão é como o UIB gerência as transações. O caso é que o SELECT executado dentro de uma transação(Utilizando o drive UIB), comita a mesma antes do COMMIT propriamente dito. Então quando o rollback é executado, não há o que voltar.
Baseado nisso. Tentei até algo como:
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 SQLConnection1.Commit(T_ID1); except SQLConnection1.Rollback(T_ID1); end;
Ou seja, só dou o start na transação depois do fim do laço. Mas mesmo assim, o problema persiste. Continuo os estudos para resolver este problema. Se alguém puder contribuir...
[]'s
Gostei + 0
13/08/2010
Junior Miranda
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;
[]'s
Gostei + 0
13/08/2010
Junior Miranda
[]'s
Gostei + 0
14/08/2010
Marco Salles
ClientDataSet1IT_NUM.AsInteger := SqlQuery2.Fields.Fields[0].AsInteger;
ClientDataSet1.Post; Faria com Update ... Igualmente vc Fez com o 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();
Deixaria a Transação no Inicio do Bloco ( apesar que não é bom uma Transação ficar muito Tempo Aberta) e no fim comitaria ou desfazeria Me parece estranho é vc misturar o controle Transacional do MIDAS ( ApplayUpdates ) com a Transação propriamente dita
Gostei + 0
14/08/2010
Junior Miranda
ClientDataSet1IT_NUM.AsInteger := SqlQuery2.Fields.Fields[0].AsInteger;
ClientDataSet1.Post; Faria com Update ... Igualmente vc Fez com o 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();
Deixaria a Transação no Inicio do Bloco ( apesar que não é bom uma Transação ficar muito Tempo Aberta) e no fim comitaria ou desfazeria Me parece estranho é vc misturar o controle Transacional do MIDAS ( ApplayUpdates ) com a Transação propriamente dita
Já testei desta forma também! O problema é que como o select está dentro da transação e em loop, a cada volta, ele (o select), commita o ExecSql anterior. Isto antes do commit propriamente dito. Então, quando há uma excessão, o rollback não funcionaria como devido. Quero garantir a atomicidade através da transação. 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.
[]'s
Gostei + 0
14/08/2010
Marco Salles
Já testei desta forma também! O problema é que como o select está dentro da transação e em loop, a cada volta, ele (o select), commita o ExecSql anterior. Isto antes do commit propriamente dito. Então, quando há uma excessão, o rollback não funcionaria como devido. Quero garantir a atomicidade através da transação. 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.
[]'s
Gostei + 0
14/08/2010
Junior Miranda
Que parte do já utilizei desta forma vc não entendeu?????
Já testei desta forma também! O problema é que como o select está dentro da transação e em loop, a cada volta, ele (o select), commita o ExecSql anterior. Isto antes do commit propriamente dito. Então, quando há uma excessão, o rollback não funcionaria como devido. Quero garantir a atomicidade através da transação. 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.
Me mostra nesta minha última citação, onde indico o uso do clientdaset. Eu poderia devolver a sua ofensa. Mas não vou fazer isso não. Se eu fizesse isto, estaria me comportando como moleque. Coisa que não sou. Dá uma pesquisada no drive UIB e veja se o que eu estou dizendo é uma mentira. O que seria do mundo se fossem estes "Senhores do Conhecimento".
[]'s
Gostei + 0
14/08/2010
Marco Salles
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;
.............continua Codigo if ClientDataSet1.ApplyUpdates(0) <> 0 then .... Finaliza o codigo end;
Sem
[]'s
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)