DBExpress Controle de Transacao
11/02/2013
0
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
Post mais votado
14/02/2013
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.
Perivaldo Martins
Mais Posts
14/02/2013
Volmir Santos
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}
14/02/2013
Perivaldo Martins
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!
15/02/2013
Perivaldo Martins
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!
15/02/2013
Marco Salles
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
15/02/2013
Perivaldo Martins
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!
15/02/2013
Marco Salles
Tudo bem ... quanto tempo . a fila anda né
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 ...
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;
È 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
15/02/2013
Perivaldo Martins
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!
15/02/2013
Marco Salles
[]sds
15/02/2013
Perivaldo Martins
[]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!
15/02/2013
Marco Salles
Sim Martins ele mesmo ... Nos na peleja e apredendo juntos . Infelismente na migração muitos tópicos ficarm mau formatados
Bons tempos aqueles
[]sds
16/02/2013
Perivaldo Martins
Parabéns pelo seu blog, tem muita coisa boa lá, muitas informações.
Abraços meu amigo!
Boa sorte e bons códigos!
15/06/2018
Wellington Silva
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 />
Clique aqui para fazer login e interagir na Comunidade :)