Fórum ClientDataSets X Transações... Como é/deve ser o controle ? #45212
29/06/2004
0
Poderiam me esclarecer duas dúvidas relacionadas à Transações com ClientDataSets ?
Eu utilizo os ClientDataSets apenas para exibição da dados onde necessito de navegação bidirecional, nas demais operações utilizo SQLDataSets envoltos em transações explicitamente controladas por mim...
-> Mas e se eu quisesse utilizar-me de componentes data-aware e trabalhar o insert/edit/delete diretamente no CDS, existiria a necessidade ou seria recomendável controlar a transação? Não me recordo onde, mas vi uma colocação de que a Midas controla sozinha a transação...
-> A segunda dúvida é que já vi colegas controlarem as transações até mesmo em selects (unidirecionais, sem CDS ligados), e isso eu não faço... é necessário, ou é recomendável ?
Fiz um pequeno teste e se eu tentar controlar a transação de um select num SQLDataSet que tem um ClientDataSet ligado à ele ocorre um erro de ´Cursor not returned´, o que sugere a resposta da minha dúvida anterior que, neste caso, a transação fica por conta da Midas, mas não tenho certeza...
Trabalho com dbExpress + FB 1.5...
Agredeço desde já !
[]´s
Vinicius.
Vinicius2k
Curtir tópico
+ 0Posts
29/06/2004
Afarias
|trabalhar o insert/edit/delete diretamente no CDS, existiria a
|necessidade ou seria recomendável controlar a transação?
Não e Não
|Não me recordo onde, mas vi uma colocação de que a Midas controla
|sozinha a transação...
Sim
|-> A segunda dúvida é que já vi colegas controlarem as transações até
|mesmo em selects (unidirecionais, sem CDS ligados), e isso eu não
|faço... é necessário, ou é recomendável ?
é bom sempre controlar as transações... nos casos de consulta, o importante é manter a transação aberta o menor tempo possível e sempre fechá-la com commit.
|Fiz um pequeno teste e se eu tentar controlar a transação de um select
|num SQLDataSet que tem um ClientDataSet ligado à ele ocorre um erro
|de ´Cursor not returned´, o que sugere a resposta da minha dúvida
|anterior que, neste caso, a transação fica por conta da Midas, mas não
|tenho certeza...
Sim, desde que vc não controle a transação ela será aberta e encerrada automaticamente pelo midas/dbx.
É importante q transações ligadas a DataSets com CDS *nunca* sejam usadas por DataSets q não estão ligados a CDSs.
T+
Gostei + 0
29/06/2004
Vinicius2k
Mas ainda ficou uma dúvida... veja minha função para abertura de um DataSet usando transação e com CDS ligado :
function dbxDSOpen(aDataSet: TSQLDataSet; aClientDataSet: TClientDataSet; aTransactionID: Integer = 1): Boolean; var SC: TSQLConnection; TD: TTransactionDesc; CR: TCursor; begin Result:= False; CR:= Screen.Cursor; Screen.Cursor:= crSQLWait; SC:= aDataSet.SQLConnection; TD.TransactionID:= aTransactionID; TD.IsolationLevel:= xilReadCommitted; try SC.StartTransaction(TD); try with aDataSet do begin Prepared:= True; Open; end; aClientDataSet.Open; // antes aqui era o Commit(TD) SC.Commit(TD); // antes aqui era o CDS.Open; Result:= True; except on E: Exception do begin MsgErro(´blá... blá... blá... ´ + #13 + E.Message); SC.Rollback(TD); end; end; except on E: Exception do begin MsgErro(´blá... blá... blá... ´ + 13 + E.Message); end; end; Screen.Cursor:= CR; end;
Nas duas linhas q eu assinalei com ´//´ as posições eram invertidas... primeiro eu commitava a transação e depois abria o CDS, daí ocorria o erro ´Cursor Unknow´ (e não ´not returned´, como eu havia descrito) a partir da segunda abertura do DataSet, a primeira funcionava perfeitamente... invertidas as posições tudo passou a funcionar normalmente...
A causa do problema era essa inversão, mas porque? ou não estava errado e da forma atual o CDS não está envolto na transação?
T+
Gostei + 0
29/06/2004
Afarias
não deveria abrir a transação
|| Prepared:= True;
Não é necessário preparar
|| Open;
Não deveria nunca Abrir o SQLDataSet (ou qualquer DataSet ligado a um CDS)
||SC.Commit(TD); // antes aqui era o CDS.Open;
Não deveria ´commitar´
olha, tirando os detalhes do DBX (que não uso ou conheço pq meu delphi é o 5) -- todo seu código deveria ser resumido a no máximo::
Result:= False; Screen.Cursor:= crSQLWait; try try aClientDataSet.Open; Result := True; except on E: Exception do MsgErro(´blá... blá... blá... ´ + #13 + E.Message); end; finally Screen.Cursor := crDefault; end;
tudo isso desde que vc não tenha antes aberto ´manualmente´ a transação. o q é importante entender é q, na linha::
aClientDataSet.Open;
o q acontece é::
1- atransação do SQLDataSet é ´startada´
2- o SQLDataSet é aberto
3- o SQLDataSet é ´corrido´ até o fim e todos os registros são enviados ao provider (e dai ao buffer CDS)
4- o SQLDataSet é fechado
5- a transação é ´commitada´
em apenas 1 linha de código!! :D
T+
Gostei + 0
29/06/2004
Vinicius2k
Ficou explícita minha quase total falta de conhecimento dos CDSs... ele faz tudo sozinho... acho que preciso perder o hábito de tentar controlar tudo (herança do Clipper) e estudar mais sobre CDSs... :?
Conheces algum material específico sobre CDS ? além do help do Delphi, é claro...
De fato eu imaginava algo parecido, pq por exemplo, como agiria a propriedade ´PacketRecords´? logicamente limitando o trabalho do DataSet e para tal o CDS precisa ´assumir o controle´ do DataSet, fazendo todo o trabalho... e ´FetchParams´ então? se o CDS interage diretamente com o DataSet não existe a menor necessidade que eu interfira...
Obrigado mais uma vez afarias !
T+
Gostei + 0
29/06/2004
Afarias
pra ser mais ´justo´ :: quem faz praticamente tudo realmente é o provider!! o CDS apenas avisa a ele q precisa dos dados
;)
| Conheces algum material específico sobre CDS ?
Os materiais q conheço (e os melhores materiais em tudo relacionado a Borland) estão na página http://bdn.borland.com/ e nos News Groups da Borland (além do Help q vc já citou! -- e q tb acho muito bom).
beleza cara?! :D
T+
Gostei + 0
29/06/2004
Vinicius2k
brigadão afarias !
T+
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)