1. Méthode de sortie
Au départ, je pensais que le processus se terminerait immédiatement après l'exécution de la méthode Exit, mais j'ai changé d'avis après avoir créé un exemple pour le tester. S'il te plaît regarde ça
Par exemple, le drapeau reçoit finalement la valeur « C ».
=================================================== ===============================================
var
drapeau : chaîne ;
commencer
essayer
drapeau := 'A';
Sortie;
drapeau := 'B';
enfin
drapeau := 'C';
fin;
drapeau := 'D';
fin;
=================================================== ===============================================
Analyse : quelle que soit la fin de la clause try, la clausefinal est toujours exécutée. (Merci l'internaute ylmg)
2. Un petit problème qui peut paralyser tout le système
Dans la conception d'un système de base de données, les opérations de transaction sont souvent utilisées pour garantir l'intégrité des données. Cependant, une mauvaise conception peut facilement avoir un impact relativement important. L'exemple suivant montre que même si l'intégrité des données est garantie, le système peut cesser complètement de fonctionner :
=================================================== ===============================================
AdoConnection1.BeginTrans ;
essayer
...
if application.MessageBox('Êtes-vous sûr de supprimer ?', 'Question', MB_YESNO+MB_ICONQUESTION)<>IDOui alors //(1)
commencer
...
fin;
Application.MessageBox('Opération échouée', 'Avertissement', MB_OK //(2) ;
AdoConnection1.CommitTrans;
sauf
Application.MessageBox('Opération échouée', 'Avertissement', MB_OK //(3) ;
AdoConnection1.RollbackTrans;
fin;
=================================================== ===============================================
Analyse : les problèmes dans le code ci-dessus sont tous causés par Application.MessageBox dans (1), (2) et (3), mais ce n'est pas Application.MessageBox lui-même qui provoque le problème, mais il bloque le programme et nécessite l'utilisation de l'utilisateur. intervention, puis continuer à effectuer les opérations suivantes ; si l'utilisateur quitte l'ordinateur à ce moment-là, ou ne confirme pas le fonctionnement de ces boîtes de dialogue, il est concevable que l'ensemble du système soit en état d'attente car cette transaction n'est pas terminée. .
Pour éviter ce problème, il y a deux principes :
(1) Une fois la transaction démarrée, le programme peut automatiquement mettre fin à la transaction sans intervention de l'utilisateur ;
(2) Effectuez l’opération la plus courte de la transaction.
3. essayer... sauf... structure finale
Voici un exemple illustrant la structure try ou un exemple d'utilisation d'opérations de transaction :
Le code en question :
=================================================== ===============================================
essayer
...
AdoConnection1.BeginTrans ;
...
AdoConnection1.CommitTrans;
sauf
AdoConnection1.RollbackTrans;
fin;
=================================================== ===============================================
Analyse : si une exception se produit dans le code après avoir essayé AdoConnection1.BeginTrans, elle passera à AdoConnection1.RollbackTrans pour l'exécution. Cependant, AdoConnection1 n'a pas démarré la transaction en raison d'une erreur, une erreur s'est donc produite lors de l'exécution d'AdoConnection1.RollbackTrans.
Code correct : =============================================== = ==================================================
AdoConnection1.BeginTrans ;
essayer
...
...
AdoConnection1.CommitTrans;
sauf
AdoConnection1.RollbackTrans;
fin;
=================================================== ===============================================
En bref, la structure de try est utilisée pour protéger les opérations anormales. Si une exception se produit entre try...sauf, l'opération entre except...end sera exécutée lors de la conception de la commande try, vous devez faire attention à la rationalité. de l'architecture.
4. Fraude à sa propre protection des transactions
Lors de la création d'un logiciel d'application de base de données, nous devons souvent rencontrer les problèmes suivants : juger les données d'origine puis apporter les modifications correspondantes. Ce problème semble relativement simple, mais si l'on considère qu'il y a d'autres personnes sur le réseau qui utilisent le même système, alors il faut considérer la possibilité de changements accidentels. Mon collègue a été négligent, même s'il a réfléchi au problème du multi-utilisateur après mes invites, il a quand même écrit le code problématique :
=================================================== ===============================================
var
annoncesTemp : TAdoDataSet ;
isOk : booléen ;
commencer
adsTemp := TAdoDataSet.Create(self);
essayer
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'sélectionnez fid, fnumber de tb1 où fid=120';
annoncesTemp.Open ;
isOk := adsTemp.FieldByName('fnumber').AsInteger>100;
enfin
annoncesTemp.Free ;
fin;
sinon, c'est ok, alors
Sortie;
AdoConnection1.BeginTrans ;
essayer
AdoConnection1.Execute('mettre à jour tb1 set ffull=ffull + 1 à partir de tb1 où fid=120';
...
...
AdoConnection1.CommitTrans;
sauf
AdoConnection1.RollbackTrans;
fin;
fin;
=================================================== ===============================================
Analyse : je ne sais pas si vous avez vu le problème. Les données sont jugées avant AdoConnection1.BeginTrans, puis AdoConnection1.Execute est utilisé pour modifier les données. Si les données sont partagées, alors pendant la période suivant le jugement. AdoConnection1.BeginTrans, tb1 Les données peuvent avoir changé et cette protection des transactions n'est d'aucune utilité.
La méthode correcte est que le jugement et la modification doivent être les mêmes données. Les exemples suivants montrent deux méthodes (la différence est que l'emplacement où la transaction est démarrée est différent) :
Code 1 (après utilisation de la protection des transactions, les mêmes données sont jugées et modifiées) :
=================================================== ===============================================
var
annoncesTemp : TAdoDataSet ;
isOk : booléen ;
commencer
AdoConnection1.BeginTrans ;
essayer
adsTemp := TAdoDataSet.Create(self);
essayer
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'sélectionnez fid, fnumber, ffull à partir de tb1 où fid=120';
annoncesTemp.Open ;
si adsTemp.FieldByName('fnumber').AsInteger>100 alors
commencer
annoncesTemp.Edit ;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
annoncesTemp.Post ;
fin;
enfin
annoncesTemp.Free ;
fin;
AdoConnection1.CommitTrans;
sauf
AdoConnection1.RollbackTrans;
fin;
fin;
=================================================== ===============================================
Code 2 (en utilisant la capture d'exception, si le jugement et la modification ne sont pas les mêmes données, une exception se produira pendant adsTemp.Post. Il s'agit d'une fonctionnalité de l'objet ADODataSet) :
=================================================== ===============================================
var
annoncesTemp : TAdoDataSet ;
isOk : booléen ;
commencer
adsTemp := TAdoDataSet.Create(self);
essayer
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'sélectionnez fid, fnumber, ffull à partir de tb1 où fid=120';
annoncesTemp.Open ;
si adsTemp.FieldByName('fnumber').AsInteger>100 alors
commencer
AdoConnection1.BeginTrans ;
essayer
annoncesTemp.Edit ;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
annoncesTemp.Post ;
AdoConnection1.CommitTrans;
sauf
AdoConnection1.RollbackTrans;
fin;
fin;
enfin
annoncesTemp.Free ;
fin;
fin;