DBExpress Controle de Transacao
Boa tarde,
até entao sempre trabalhei com zeos e postgres, porem me surgiu um projeto que vou ter q usar o Firebird e nao tenho muita experiencia com esta situacao, gostaria se alguem pudesse me dar algumas dicas sobre a seguinte situacao
Estou utilizando "Delphi XE3" pra conexao vou utilizar os componentes da paleta "DBExpress"
eu precisaria fazer o controle de Transação ?
ex:
TSQLConection1.StartTransaction();
ou o DBExpress faz este controle automatico de der algum erro ele da um roolback automatico ou nao
eu preciso dar um TSQLConection1.roolback();
como ficaria no caso de multiplas transacoes ?
nao vou utilizar ClientDaset
vou usar assim
TSQLConection1 => TSQLQuerry
TSQLQuerry1.close;
TSQLQuerry1.sql.clear;
TSQLQuerry1.sql.add(''Insert into teste(codigo,nome)values(:a1,:a2)'');
TSQLQuerry1.params[0].asinteger:=1;
TSQLQuerry1.params[1].asstring:=''Teste'';
TSQLQuerry.ExecSQL;
+/- assim estou utlizando
até entao sempre trabalhei com zeos e postgres, porem me surgiu um projeto que vou ter q usar o Firebird e nao tenho muita experiencia com esta situacao, gostaria se alguem pudesse me dar algumas dicas sobre a seguinte situacao
Estou utilizando "Delphi XE3" pra conexao vou utilizar os componentes da paleta "DBExpress"
eu precisaria fazer o controle de Transação ?
ex:
TSQLConection1.StartTransaction();
ou o DBExpress faz este controle automatico de der algum erro ele da um roolback automatico ou nao
eu preciso dar um TSQLConection1.roolback();
como ficaria no caso de multiplas transacoes ?
nao vou utilizar ClientDaset
vou usar assim
TSQLConection1 => TSQLQuerry
TSQLQuerry1.close;
TSQLQuerry1.sql.clear;
TSQLQuerry1.sql.add(''Insert into teste(codigo,nome)values(:a1,:a2)'');
TSQLQuerry1.params[0].asinteger:=1;
TSQLQuerry1.params[1].asstring:=''Teste'';
TSQLQuerry.ExecSQL;
+/- assim estou utlizando
Volmir Santos
Curtidas 0
Melhor post
Perivaldo Martins
14/02/2013
Olá!
Usando DBX, vc poderá controlar as transações ou no caso de usar ClientDataSet, deixar que ele faça isso para vc, mas isso não o impede de também controlá-las mesmo usando o ClientDataSet.
Se vc for utiliza os componentes (TDataSetProvider + TClientDataSet + TDataSource), não precisará ter muita preocupação com as transações pq a Midas cuidará disso para vc. Se vc não conhece ou nunca trabalhou com ClientDataSet dê uma pesquisada, aqui memso no forum tem muita coisa, tópicos falando sobre ApplyUpdate e como o ApplyUpdate não levanta exceptions, veja algo sobre o OnReconcilieError, onde vc poderá saber se houve algum erro.
Exemplo:
Controlando as transações explicítamente.
Dependendo da versão do Delphi q vc estiver usando, se for XE2 por exemplo, o DBX4 tem algumas mudanças e melhorias.
Declare no User Data.DBXCommon
Algo mais ou menos como descrito acima, assim vc tem controle sobre as transações.
Para maiores informações busque aqui no fórum ou post suas dúvidas, tentaremos ajudá-lo.
Boa sorte e bons códigos.
Usando DBX, vc poderá controlar as transações ou no caso de usar ClientDataSet, deixar que ele faça isso para vc, mas isso não o impede de também controlá-las mesmo usando o ClientDataSet.
Se vc for utiliza os componentes (TDataSetProvider + TClientDataSet + TDataSource), não precisará ter muita preocupação com as transações pq a Midas cuidará disso para vc. Se vc não conhece ou nunca trabalhou com ClientDataSet dê uma pesquisada, aqui memso no forum tem muita coisa, tópicos falando sobre ApplyUpdate e como o ApplyUpdate não levanta exceptions, veja algo sobre o OnReconcilieError, onde vc poderá saber se houve algum erro.
Exemplo:
with CDS1 do begin Append; .... Post; end; If ApplyUpdates(0)> 0 then ShowMessage('Houve um erro ao tentar gravar o registro!') else ShowMessage('Registro gravado com sucesso!');
Controlando as transações explicítamente.
var Trans: TTransactionDesc; begin with CDS1 do begin Append; ... Post; Trans.TransactionID:= 1; Trans.IsolationLevel:= xilReadCommitted; SQLConnection1.StartTransaction(Trans); if ApplyUpdates(0) = 0 then SQLConnection1.Commit(Trans) else SQLConnection1.Rollback(Trans); end;
Dependendo da versão do Delphi q vc estiver usando, se for XE2 por exemplo, o DBX4 tem algumas mudanças e melhorias.
Declare no User Data.DBXCommon
var Trans: TDBXTransaction; begin Trans := SQLConnection1.BeginTransaction; try with CDS1 do begin Append; ... Post; end; If CDS1.ApplyUpdates(0) = 0 then SQLConnection1.CommitFreeAndNil(Trans); ShowMessage('Os Dados foram gravados com sucesso!'); Finally SQLConnection1.RollbackFreeAndNil(Trans); end; end;
Algo mais ou menos como descrito acima, assim vc tem controle sobre as transações.
Para maiores informações busque aqui no fórum ou post suas dúvidas, tentaremos ajudá-lo.
Boa sorte e bons códigos.
GOSTEI 2
Mais Respostas
Volmir Santos
11/02/2013
Essa é que é a minha duvida pois nao estou trabalhando com esta estrutura(TDataSetProvider + TClientDataSet + TDataSource)
Estou passando os dados por parametro e uso o TSQLQuerry
Algo tipo:
{Aqui nao sei se Preciso iniciar uma Transacao}
TsqlQuery.sql.clear;
TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)');
TsqlQuery.params[0].asinteger:=1;
TsqlQuery.params[1].asString :='Nome';
TsqlQuery.ExecSQL;
{Aqui nao sei se Preciso Commitar a Transacao}
Estou passando os dados por parametro e uso o TSQLQuerry
Algo tipo:
{Aqui nao sei se Preciso iniciar uma Transacao}
TsqlQuery.sql.clear;
TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)');
TsqlQuery.params[0].asinteger:=1;
TsqlQuery.params[1].asString :='Nome';
TsqlQuery.ExecSQL;
{Aqui nao sei se Preciso Commitar a Transacao}
GOSTEI 0
Perivaldo Martins
11/02/2013
Essa é que é a minha duvida pois nao estou trabalhando com esta estrutura(TDataSetProvider + TClientDataSet + TDataSource)
Estou passando os dados por parametro e uso o TSQLQuerry
Algo tipo:
{Aqui nao sei se Preciso iniciar uma Transacao}
TsqlQuery.sql.clear;
TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)');
TsqlQuery.params[0].asinteger:=1;
TsqlQuery.params[1].asString :='Nome';
TsqlQuery.ExecSQL;
{Aqui nao sei se Preciso Commitar a Transacao}
Estou passando os dados por parametro e uso o TSQLQuerry
Algo tipo:
{Aqui nao sei se Preciso iniciar uma Transacao}
TsqlQuery.sql.clear;
TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)');
TsqlQuery.params[0].asinteger:=1;
TsqlQuery.params[1].asString :='Nome';
TsqlQuery.ExecSQL;
{Aqui nao sei se Preciso Commitar a Transacao}
Ficaria algo mais ou menos assim.
Transacao := SQLConnectio.BeginTransaction; // Inicia a transação TsqlQuery.Close; TsqlQuery.sql.clear; TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)'); TsqlQuery.params[0].asinteger:=1; TsqlQuery.params[1].asString :='Nome'; try TsqlQuery.ExecSQL; SQLConnection1.CommitFreeAndNil(Transacao) //Commita a transação except On E: Exception do begin SQLConnection1.RollbackFreeAndNil(Transacao); // Se houver algum erro, rollback ShowMessage('Houve um erro '+ #13 + E.Message); end; end; ...
Boa sorte e bons códigos!
GOSTEI 0
Volmir Santos
11/02/2013
Ok
Obrigado pelas dicas vou testar
Obrigado pelas dicas vou testar
GOSTEI 0
Perivaldo Martins
11/02/2013
Ok
Obrigado pelas dicas vou testar
Obrigado pelas dicas vou testar
OK! Teste e retorne com o resultado, se precisar de mais ajuda, estamos aqui para tentar ajudar.
Boa sorte e bons códigos!
GOSTEI 0
Marco Salles
11/02/2013
Blz martins ? Vc é o Martins do velho Forum Clube delphi ???
Então vc faz mais ou menos assim
eu faria assim tb so que eu utilizaria
SQLConnection1.RollbackIncompleteFreeAndNil(Transacao); e a estrutura colocaria dentro do try Finallky
try
TsqlQuery.ExecSQL; // deu certo comita deu errrado Finnaly
SQLConnection1.CommitFreeAndNil(Transacao) //Commita a transação
ShowMessage('Dados Salvos com sucesso !!!');
finally
QLConnection1.RollbackIncompleteFreeAndNil(Transacao);//dando certo ou dando errado o método é capaz de dar Roolbak uu
desconsiderar caso ja tenha dado o Commit
Qual a diferença aos meus olhos . Na prática os dois irão funcionar , mas devemos sempre programar para a Regra e raramente para a exceção ... O Programa deve ter muito mais try finally e pouquissimos try excpet ( conceitualmente é
como se a gente soubesse que vai pode falhar e não fizemos nada para evitar a falha a não ser apresenta-la .. Acredito que
o surgimento do RollbackIncompleteFreeAndNil venha a dar este aporte conceitual além de levantar possiveis exceçoes
quando se dar um SQLConnection1.RollbackFreeAndNil(Transacao); de uma transação que por alguma razão não exista , entre outras coisas mais
[]sds e é so uma opinião sem entrar em conflito com o que vc corretamente colocou . Abraços
Então vc faz mais ou menos assim
Transacao := SQLConnectio.BeginTransaction; // Inicia a transação TsqlQuery.Close; TsqlQuery.sql.clear; TsqlQuery.sql.add('Insert Into Teste (codigo, nome)Values(:codigo, :nome)'); TsqlQuery.params[0].asinteger:=1; TsqlQuery.params[1].asString :='Nome'; try TsqlQuery.ExecSQL; SQLConnection1.CommitFreeAndNil(Transacao) //Commita a transação except On E: Exception do begin SQLConnection1.RollbackFreeAndNil(Transacao); // Se houver algum erro, rollback ShowMessage('Houve um erro '+ #13 + E.Message); end; end; ...
eu faria assim tb so que eu utilizaria
SQLConnection1.RollbackIncompleteFreeAndNil(Transacao); e a estrutura colocaria dentro do try Finallky
try
TsqlQuery.ExecSQL; // deu certo comita deu errrado Finnaly
SQLConnection1.CommitFreeAndNil(Transacao) //Commita a transação
ShowMessage('Dados Salvos com sucesso !!!');
finally
QLConnection1.RollbackIncompleteFreeAndNil(Transacao);//dando certo ou dando errado o método é capaz de dar Roolbak uu
desconsiderar caso ja tenha dado o Commit
Qual a diferença aos meus olhos . Na prática os dois irão funcionar , mas devemos sempre programar para a Regra e raramente para a exceção ... O Programa deve ter muito mais try finally e pouquissimos try excpet ( conceitualmente é
como se a gente soubesse que vai pode falhar e não fizemos nada para evitar a falha a não ser apresenta-la .. Acredito que
o surgimento do RollbackIncompleteFreeAndNil venha a dar este aporte conceitual além de levantar possiveis exceçoes
quando se dar um SQLConnection1.RollbackFreeAndNil(Transacao); de uma transação que por alguma razão não exista , entre outras coisas mais
[]sds e é so uma opinião sem entrar em conflito com o que vc corretamente colocou . Abraços
GOSTEI 1
Perivaldo Martins
11/02/2013
Olá Marco Salles, seja bem vindo ao tópico. Tudo bem com vc meu amigo? Sim sou o Martins do bom e velho fórum Clube Delphi, estamos de volta, rsrsrsrs.
Marco, quanto ao código que vc postou.
Concordo com você, sempre tentando mostrar um bom caminho, meu amigo, estou sempre q possível acompanhando o [url]http://marcosalles.wordpress.com[/url], Marco ao longo dos estudos com DBX4, tenho visto códigos como os de baixo:
Informando o isolamento, qual a diferença na prática entre essas duas instruções?
Quanto ao bloco Try Finally End no lugar d Try Except End, usando o método RollbackIncompleteFreeAndNil, é bem interessante mesmo.
Boa sorte e bons códigos!
Marco, quanto ao código que vc postou.
try TsqlQuery.ExecSQL; // deu certo comita deu errrado Finnaly SQLConnection1.CommitFreeAndNil(Transacao) //Commita a transação ShowMessage('Dados Salvos com sucesso !!!'); finally QLConnection1.RollbackIncompleteFreeAndNil(Transacao);//dando certo ou dando errado o método é capaz de dar Roolbak uu desconsiderar caso ja tenha dado o Commit
Concordo com você, sempre tentando mostrar um bom caminho, meu amigo, estou sempre q possível acompanhando o [url]http://marcosalles.wordpress.com[/url], Marco ao longo dos estudos com DBX4, tenho visto códigos como os de baixo:
var trans: TDbxTransaction; begin trans := SQLConnection1.BeginTransaction; --------------------------------------------------------------- var trans: TDbxTransaction; begin Trans := SQLConnection1.BeginTransaction(TDBXIsolations.ReadCommitted); try ...
Informando o isolamento, qual a diferença na prática entre essas duas instruções?
Quanto ao bloco Try Finally End no lugar d Try Except End, usando o método RollbackIncompleteFreeAndNil, é bem interessante mesmo.
Boa sorte e bons códigos!
GOSTEI 1
Marco Salles
11/02/2013
Olá Marco Salles, seja bem vindo ao tópico. Tudo bem com vc meu amigo? Sim sou o Martins do bom e velho fórum Clube Delphi, estamos de volta, rsrsrsrs.
Tudo bem ... quanto tempo . a fila anda né
Concordo com você, sempre tentando mostrar um bom caminho, meu amigo, estou sempre q possível acompanhando o http://marcosalles.wordpress.com,
Uma satisfação te-lo comoconvidado noblog . Infelismente nunca recebi um alô seu . Nen pensei que pudesse ler as bobagens
A ultima que escrevi foi ontem e fala de DbXreader
http://marcosalles.wordpress.com/2013/02/14/definir-em-rumtime-ou-passar-como-parametro-o-caminho-do-banco-em-datasnap-dbxreader-dbx4/
dois minutos so para Leitura ( não gasta mais , pouco código e muita conversa . Mas ate hj não vi algo similar a respeito
sobre como definir em rumtime utilizando o Dbxreader
Marco ao longo dos estudos com DBX4, tenho visto códigos como os de baixo:
#Código
var trans: TDbxTransaction; begin trans := SQLConnection1.BeginTransaction; --------------------------------------------------------------- var trans: TDbxTransaction; begin Trans := SQLConnection1.BeginTransaction(TDBXIsolations.ReadCommitted); try ...
Informando o isolamento, qual a diferença na prática entre essas duas instruções?
O Delphi é RAD amigo .. E a instrução SQLConnection1.BeginTransaction é mais RAD do que a instrução SQLConnection1.BeginTransaction(TDBXIsolations.ReadCommitted) ... Simples assim Mesmo
Sobre isto ai um detalhe importante . Tem mais duas formas (Talves esta fosse de fato uma dúvida)
tr:=SQLConnection1.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted); ou tr:=SQLConnection1.DBXConnection.BeginTransaction;
Essas duas formas estão erradas ... Ja as utilizei , porém sempre deu erro de Invalid Transactional Object
Infelismente quando a tecnologia é nova a gente procura artigos . E se esses artigos nos orientam de forma equivocada
nos levamos á frente o erro ... Pq não sedeve utilizar essas duas formas anteriores ???? Porque
DBXConnection é uma interface para o objeto dbExpress subjacente para uma conexão de banco de dados
Em outras palavras vc deve utilizar nos objetos FConnetion:TDBXConnection e não nos Objetos da classe TSQLConnection.
Em outras palavras , isto é Válido
var trans: TDbxTransaction; FConnetion:TDBXConnection; begin //nivel de isolamento.. tr:=FConnetion.BeginTransaction(TDBXIsolations.ReadCommitted); ou tr:=FConnetion.BeginTransaction;
Quanto ao bloco Try Finally End no lugar d Try Except End, usando o método RollbackIncompleteFreeAndNil, é bem interessante mesmo.
È verdade Martins , a partir do delphi 2007 o controle Transactional mudou muito . Agora a transação não é mais inicializa , mas sim Instanciada e quem controla tudo agora é o Objeto da classe TDBXTransaction
[]sds e abraços
GOSTEI 1
Perivaldo Martins
11/02/2013
Uma satisfação te-lo como convidado noblog . Infelismente nunca recebi um alô seu . Nen pensei que pudesse ler as bobagens
A ultima que escrevi foi ontem e fala de DbXreader
http://marcosalles.wordpress.com/2013/02/14/definir-em-rumtime-ou-passar-como-parametro-o-caminho-do-banco-em-datasnap-dbxreader-dbx4/
dois minutos so para Leitura ( não gasta mais , pouco código e muita conversa . Mas ate hj não vi algo similar a respeito
sobre como definir em rumtime utilizando o Dbxreader
Acompanho sim, e não tem nenhuma bobagem por lá, sempre muita informação, eu nunca havia comentado, mas a partir de então, sempre q possível deixarei meu comentário sobre o assunto ou tentarei interagir.
O Delphi é RAD amigo .. E a instrução SQLConnection1.BeginTransaction é mais RAD do que a instrução SQLConnection1.BeginTransaction(TDBXIsolations.ReadCommitted) ... Simples assim Mesmo
É verdade, completamente RAD.
tr:=SQLConnection1.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted); ou tr:=SQLConnection1.DBXConnection.BeginTransaction;
Essas duas formas estão erradas ... Ja as utilizei , porém sempre deu erro de Invalid Transactional Object
Infelismente quando a tecnologia é nova a gente procura artigos . E se esses artigos nos orientam de forma equivocada
nos levamos á frente o erro ... Pq não sedeve utilizar essas duas formas anteriores ???? Porque
DBXConnection é uma interface para o objeto dbExpress subjacente para uma conexão de banco de dados
Foi o que encontrei quando procurei na Embarcadero, documentação sobre o assunto. Lá diz exatamento o que você já fala aqui. DBXConnection é uma interface para o objeto dbExpress subjacente para uma conexão de banco de dados. Normalmente, você não precisa de interagir diretamente com este objeto dbExpress porque todos os seus métodos estão à disposição, direta ou indiretamente, na implementação de TSQLConnection .
var trans: TDbxTransaction; FConnetion:TDBXConnection; begin //nivel de isolamento.. tr:=FConnetion.BeginTransaction(TDBXIsolations.ReadCommitted); ou tr:=FConnetion.BeginTransaction;
Interessante, como um tópico sobre uma dúvida quanto ao controle transacional usando DBX se torna uma aula sobre o assunto, muito bom, os usuários do fórum agradecem. Obrigado meu amigo Marco Salles, abraços.
Boa sorte e bons códigos!
GOSTEI 1
Marco Salles
11/02/2013
aula foi aquela do NestedDataSet .. eu vc e o Adriano Santos . Lembra ???
[]sds
[]sds
GOSTEI 0
Perivaldo Martins
11/02/2013
aula foi aquela do NestedDataSet .. eu vc e o Adriano Santos . Lembra ???
[]sds
[]sds
Bons tempos do velho fórum, pessoal nota 10 (Adriano Santos, Nildo, Massuda, Emerson.En, Vinicius2k, Marco Salles, Afarias, Aroldo Zanela, Zoom, Gandalf.nho e outros feras).
Quanto a esse tópico que o amigo está citando é o sobre o uso dos componentes SQLConnection1 -> SQLDataSet1 -> DataSetProvider1 -> ClientDataSet1 -> DataSource1, usando Interbase 6.5, tópico q ficou grande e serviu como fonte de estudo para muitos.
Boa sorte e bons códigos!
GOSTEI 0
Marco Salles
11/02/2013
Quanto a esse tópico que o amigo está citando é o sobre o uso dos componentes SQLConnection1 -> SQLDataSet1 -> DataSetProvider1 -> ClientDataSet1 -> DataSource1, usando Interbase 6.5, tópico q ficou grande e serviu como fonte de estudo para muitos.
Sim Martins ele mesmo ... Nos na peleja e apredendo juntos . Infelismente na migração muitos tópicos ficarm mau formatados
Bons tempos aqueles
[]sds
GOSTEI 0
Perivaldo Martins
11/02/2013
É verdade Marco, pena também que muita gente boa tenha de certa forma se afastado do fórum, espero que assim como eu, eles também retornem.
Parabéns pelo seu blog, tem muita coisa boa lá, muitas informações.
Abraços meu amigo!
Boa sorte e bons códigos!
Parabéns pelo seu blog, tem muita coisa boa lá, muitas informações.
Abraços meu amigo!
Boa sorte e bons códigos!
GOSTEI 0
Wellington Silva
11/02/2013
Segui a estratégia do uso do RollbackIncompleteFreeAndNil ao invés do RollbackFreeAndNil conforme citado acima.<br />
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Data.SqlExpr.TSQLConnection.RollbackIncompleteFreeAndNil<br />
<br />
No entanto mantive também que se mostra necessário em algumas situações: BeginTransaction(TDBXIsolations.ReadCommitted)<br />
<br />
Meu relato ocorre com a versão XE4 entanto espero muito que tais problemas não ocorram em novas versões rs<br />
<br />
Abraço.<br />
<br />
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Data.SqlExpr.TSQLConnection.RollbackIncompleteFreeAndNil<br />
<br />
No entanto mantive também que se mostra necessário em algumas situações: BeginTransaction(TDBXIsolations.ReadCommitted)<br />
<br />
Meu relato ocorre com a versão XE4 entanto espero muito que tais problemas não ocorram em novas versões rs<br />
<br />
Abraço.<br />
<br />
GOSTEI 0