trabalhando com transações....
bom tarde,
gostaria da opinião(sugestão) do pessoal do fórum em relação
a minha rotina de tratamento de transações envolvendo o b.d.,
segue a rotina:
//efetuo o insert ou update
MeuProprietario.Cadastrar;
//retorna Id do Proprietario
Campos:=´GEN_ID(GENPROPRIETARIO_ID, 0)´;
Tabela:=´RDB$DATABASE´;
Complemento:=´´;
Seleciona(Campos,Tabela,Complemento);
EId.text:=DMDados.DSPrincipal.DataSet[´GEN_ID´];
//trabalho com a transação
if not DMDados.IBTFidelizando.InTransaction then
DMDados.IBTFidelizando.StartTransaction;
DMDados.IBTFidelizando.Commit;
messagedlg(´Registro Salvo.´,mtInformation,[mbOK],0);
Obs.: Minhas query´s se concentram em um único Data Module,
com a seguinte estrutura: IBDatabase->IBTransaction->IBQuery->DataSource
abro e fecho as query´s somente quando as preciso e o IBTransaction está
com os seguintes parâmetros: read_committed, rec_version. Não utilizo
componentes DataWare, faço o controle manualmente em Edit´s.
Obs2.: Observa-se q não faço uso de um Rollback numa exception por exemplo,
isso seria adequado ???...só faço uso do Rollback apenas em cadastros
Master/Detail, onde no OnClose do Form, verifico se não houve a inserção ou alteração
(pelo Id do form).
gostaria da opinião(sugestão) do pessoal do fórum em relação
a minha rotina de tratamento de transações envolvendo o b.d.,
segue a rotina:
//efetuo o insert ou update
MeuProprietario.Cadastrar;
//retorna Id do Proprietario
Campos:=´GEN_ID(GENPROPRIETARIO_ID, 0)´;
Tabela:=´RDB$DATABASE´;
Complemento:=´´;
Seleciona(Campos,Tabela,Complemento);
EId.text:=DMDados.DSPrincipal.DataSet[´GEN_ID´];
//trabalho com a transação
if not DMDados.IBTFidelizando.InTransaction then
DMDados.IBTFidelizando.StartTransaction;
DMDados.IBTFidelizando.Commit;
messagedlg(´Registro Salvo.´,mtInformation,[mbOK],0);
Obs.: Minhas query´s se concentram em um único Data Module,
com a seguinte estrutura: IBDatabase->IBTransaction->IBQuery->DataSource
abro e fecho as query´s somente quando as preciso e o IBTransaction está
com os seguintes parâmetros: read_committed, rec_version. Não utilizo
componentes DataWare, faço o controle manualmente em Edit´s.
Obs2.: Observa-se q não faço uso de um Rollback numa exception por exemplo,
isso seria adequado ???...só faço uso do Rollback apenas em cadastros
Master/Detail, onde no OnClose do Form, verifico se não houve a inserção ou alteração
(pelo Id do form).
Maikiperin
Curtidas 0
Respostas
Fsflorencio
01/03/2005
A linha
não é necessária. A transação deve ser aberta antes de passar os parâmetros para a query que está fazendo a gravação dos dados e não antes do commit.
A sequência seria assim:
if not transacao.intransation then
transacao.starttransaction;
query.sql.text := ´insert into ... values ..´;
query.execsql;//se a transação não estivesse ativa ele daria um erro neste momento;
transacao.commit;
Particularmente eu uso transações curtas e acho interessante colocar um componente applicationevents com um rollback no evento onexception informando a mensagem de erro.
No seu caso como vc não usa componentes dataware acredito que suas transações também sejam curtas. Ou você faz como sugeri, ou então você pode colocar um try except com um rollback. O importante é não ficar nenhuma transação aberta. Ok!
if not DMDados.IBTFidelizando.InTransaction then
DMDados.IBTFidelizando.StartTransaction;
não é necessária. A transação deve ser aberta antes de passar os parâmetros para a query que está fazendo a gravação dos dados e não antes do commit.
A sequência seria assim:
if not transacao.intransation then
transacao.starttransaction;
query.sql.text := ´insert into ... values ..´;
query.execsql;//se a transação não estivesse ativa ele daria um erro neste momento;
transacao.commit;
Obs2.: Observa-se q não faço uso de um Rollback numa exception por exemplo,
isso seria adequado ???...só faço uso do Rollback apenas em cadastros
Master/Detail, onde no OnClose do Form, verifico se não houve a inserção ou alteração
(pelo Id do form).
Particularmente eu uso transações curtas e acho interessante colocar um componente applicationevents com um rollback no evento onexception informando a mensagem de erro.
No seu caso como vc não usa componentes dataware acredito que suas transações também sejam curtas. Ou você faz como sugeri, ou então você pode colocar um try except com um rollback. O importante é não ficar nenhuma transação aberta. Ok!
GOSTEI 0
Maikiperin
01/03/2005
Particularmente eu uso transações curtas e acho interessante colocar um componente applicationevents com um rollback no evento onexception informando a mensagem de erro.
poderia me dar exemplo de aplicação desse componente ?
GOSTEI 0
Fsflorencio
01/03/2005
Adicione um componente TApplicationEvents (Additional) e no evento OnException você trata os erros.
ex:
procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);
begin
MessageDlg( ´ocorreu um erro inesperado!´ + #13 + E.Message, MtInformation, [mbok], 0 );
if transacao.Intransaction then
transacao.rollback;
end;
Qualquer erro que ocorrer vai dar um rollback.
Sendo assim, se você dá algum comando sql (insert, update, delete) que esteja dentro do contexto de uma transação e ocorrer um erro do tipo ´invalid variant type conversion´ vai dar um Rollback em tudo!
Por isto é imprescindível que vc use transações curtas (executar os comandos para gravar tudo de uma vez ao clicar no botão ok por exemplo, isto leva uma fração de segundos dependendo do que estiver fazendo).
ex:
procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);
begin
MessageDlg( ´ocorreu um erro inesperado!´ + #13 + E.Message, MtInformation, [mbok], 0 );
if transacao.Intransaction then
transacao.rollback;
end;
Qualquer erro que ocorrer vai dar um rollback.
Sendo assim, se você dá algum comando sql (insert, update, delete) que esteja dentro do contexto de uma transação e ocorrer um erro do tipo ´invalid variant type conversion´ vai dar um Rollback em tudo!
Por isto é imprescindível que vc use transações curtas (executar os comandos para gravar tudo de uma vez ao clicar no botão ok por exemplo, isto leva uma fração de segundos dependendo do que estiver fazendo).
GOSTEI 0