1. Método de saída
Originalmente, pensei que o processo seria encerrado imediatamente após a execução do método Exit, mas mudei de ideia depois de criar um exemplo para testá-lo. Por favor, olhe para isso
Por exemplo, ao sinalizador é finalmente atribuído o valor 'C'.
================================================= =============================================
var
bandeira: string;
começar
tentar
bandeira := 'A';
Saída;
bandeira := 'B';
finalmente
bandeira := 'C';
fim;
bandeira := 'D';
fim;
================================================= =============================================
Análise: Não importa como a cláusula try termina, a cláusula finalmente é sempre executada. (Obrigado ylmg internauta)
2. Um pequeno problema que pode paralisar todo o sistema
No projeto do sistema de banco de dados, as operações de transação são frequentemente usadas para garantir a integridade dos dados. No entanto, o projeto inadequado pode facilmente ter um impacto relativamente grande. O exemplo a seguir ilustra que, embora a integridade dos dados seja garantida, o sistema pode parar completamente de funcionar.
================================================= =============================================
AdoConnection1.BeginTrans;
tentar
...
if application.MessageBox('Tem certeza de excluir?', 'Pergunta', MB_YESNO+MB_ICONQUESTION)<>IDSim então //(1)
começar
...
fim;
Application.MessageBox('Falha na operação', 'Aviso', MB_OK);
AdoConnection1.CommitTrans;
exceto
Application.MessageBox('Falha na operação', 'Aviso', MB_OK);
AdoConnection1.RollbackTrans;
fim;
================================================= =============================================
Análise: Os problemas no código acima são todos causados por Application.MessageBox em (1), (2) e (3), mas não é o próprio Application.MessageBox que causa o problema, mas trava o programa e requer intervenção do usuário e, em seguida, continuar a realizar operações subsequentes; se o usuário sair do computador neste momento ou não confirmar a operação dessas caixas de diálogo, é concebível que todo o sistema esteja em estado de espera porque esta transação não foi realizada. terminou.
Para evitar esse problema, existem dois princípios:
(1) Após o início da transação, o programa pode encerrá-la automaticamente sem intervenção do usuário;
(2) Faça a operação mais curta na transação.
3. tente...exceto...estrutura final
A seguir está um exemplo para ilustrar a estrutura try ou um exemplo de uso de operações de transação:
O código em questão:
================================================= =============================================
tentar
...
AdoConnection1.BeginTrans;
...
AdoConnection1.CommitTrans;
exceto
AdoConnection1.RollbackTrans;
fim;
================================================= =============================================
Análise: Se ocorrer uma exceção no código AdoConnection1.BeginTrans após a tentativa, ele irá para AdoConnection1.RollbackTrans para execução, mas AdoConnection1 não iniciou a transação devido a um erro, portanto ocorreu um erro durante a execução de AdoConnection1.RollbackTrans.
Código correto: ============================================= = ================================================
AdoConnection1.BeginTrans;
tentar
...
...
AdoConnection1.CommitTrans;
exceto
AdoConnection1.RollbackTrans;
fim;
================================================= =============================================
Resumindo, a estrutura try é usada para proteger operações anormais. Se ocorrer uma exceção entre try...except, a operação entre except...end será executada. Ao projetar o comando try, você deve prestar atenção à racionalidade. da arquitetura.
4. Fraudado na proteção de assuntos próprios
Ao criar software aplicativo de banco de dados, muitas vezes precisamos encontrar os seguintes problemas: avaliar os dados originais e, em seguida, fazer as modificações correspondentes. Este problema parece relativamente simples, mas se você considerar que existem outras pessoas na rede usando o mesmo sistema, então você deve considerar a possibilidade de alterações acidentais. Meu colega foi descuidado, embora tenha considerado o problema multiusuário após minha solicitação, ele ainda escreveu o código problemático:
================================================= =============================================
var
adsTemp: TAdoDataSet;
estáOk: booleano;
começar
adsTemp := TAdoDataSet.Create(self);
tentar
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'selecione fid, fnumber de tb1 onde fid=120';
adsTemp.Open;
estáOk := adsTemp.FieldByName('fnumber').AsInteger>100;
finalmente
anúnciosTemp.Free;
fim;
se não, ok, então
Saída;
AdoConnection1.BeginTrans;
tentar
AdoConnection1.Execute('atualizar tb1 set ffull=ffull + 1 de tb1 onde fid=120';
...
...
AdoConnection1.CommitTrans;
exceto
AdoConnection1.RollbackTrans;
fim;
fim;
================================================= =============================================
Análise: Não sei se você viu o problema. Os dados são julgados antes de AdoConnection1.BeginTrans e, em seguida, AdoConnection1.Execute é usado para alterar os dados. Se os dados forem compartilhados, durante o período após o julgamento para antes. AdoConnection1.BeginTrans, tb1 Os dados podem ter mudado e esta proteção de transação é inútil.
O método correto é que o julgamento e a modificação devem ser os mesmos dados. A seguir estão dois exemplos de métodos (a diferença é que o local onde a transação é iniciada é diferente):
Código 1 (após usar proteção de transação, os mesmos dados são julgados e modificados):
================================================= =============================================
var
adsTemp: TAdoDataSet;
estáOk: booleano;
começar
AdoConnection1.BeginTrans;
tentar
adsTemp := TAdoDataSet.Create(self);
tentar
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'selecione fid, fnumber, ffull de tb1 onde fid=120';
adsTemp.Open;
se adsTemp.FieldByName('fnumber').AsInteger>100 então
começar
anúnciosTemp.Edit;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
anúnciosTemp.Post;
fim;
finalmente
anúnciosTemp.Free;
fim;
AdoConnection1.CommitTrans;
exceto
AdoConnection1.RollbackTrans;
fim;
fim;
================================================= =============================================
Código 2 (usando captura de exceção, se o julgamento e a modificação não forem os mesmos dados, ocorrerá uma exceção durante adsTemp.Post. Este é um recurso do objeto ADODataSet):
================================================= =============================================
var
adsTemp: TAdoDataSet;
estáOk: booleano;
começar
adsTemp := TAdoDataSet.Create(self);
tentar
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'selecione fid, fnumber, ffull de tb1 onde fid=120';
adsTemp.Open;
se adsTemp.FieldByName('fnumber').AsInteger>100 então
começar
AdoConnection1.BeginTrans;
tentar
anúnciosTemp.Edit;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
anúnciosTemp.Post;
AdoConnection1.CommitTrans;
exceto
AdoConnection1.RollbackTrans;
fim;
fim;
finalmente
anúnciosTemp.Free;
fim;
fim;