1.終了方法
最初はExitメソッドを実行したらすぐにプロセスが終了すると思っていましたが、実際にサンプルを作ってテストしてみると考えが変わりました。これを見てください
たとえば、flag には最終的に値「C」が割り当てられます。
================================================= =============================================
変数
フラグ: 文字列;
始める
試す
フラグ := 'A';
出口;
フラグ := 'B';
ついに
フラグ := 'C';
終わり;
フラグ := 'D';
終わり;
================================================= =============================================
分析: try 節がどのように終了しても、finally 節は常に実行されます。 (ありがとうネチズン)
2. システム全体を停止させる可能性のある小さな問題
データベース システムの設計では、データの整合性を確保するためにトランザクション操作がよく使用されますが、設計が不適切であると、データの整合性が保証されていても、システムが完全に機能しなくなる可能性があることを次の例に示します。
================================================= =============================================
AdoConnection1.BeginTrans;
試す
...
if application.MessageBox('削除してもよろしいですか?', '質問', MB_YESNO+MB_ICONQUESTION)<>IDYes then //(1)
始める
...
終わり;
Application.MessageBox('操作が失敗しました', '警告', MB_OK);
AdoConnection1.CommitTrans;
を除外する
Application.MessageBox('操作が失敗しました', '警告', MB_OK);
AdoConnection1.RollbackTrans;
終わり;
================================================= =============================================
分析: 上記のコードの問題はすべて、(1)、(2)、(3) の Application.MessageBox によって引き起こされますが、問題の原因は Application.MessageBox 自体ではなく、プログラムがハングし、ユーザーが必要になります。この時点でユーザーがコンピュータから離れるか、これらのダイアログ ボックスの操作を確認しない場合は、このトランザクションが終了していないため、システム全体が待機状態になっている可能性があります。 。
この問題を回避するには、次の 2 つの原則があります。
(1) トランザクションが開始された後、プログラムはユーザーの介入なしに自動的にトランザクションを終了できます。
(2) トランザクション内で最も短い操作を実行します。
3. 試してみます...例外...最後の構造
以下は、try 構造を示す例、またはトランザクション操作の使用例です。
問題のコード:
================================================= =============================================
試す
...
AdoConnection1.BeginTrans;
...
AdoConnection1.CommitTrans;
を除外する
AdoConnection1.RollbackTrans;
終わり;
================================================= =============================================
分析: AdoConnection1.BeginTrans を試行した後にコードで例外が発生した場合、AdoConnection1.RollbackTrans にジャンプして実行されます。ただし、AdoConnection1 はエラーのためトランザクションを開始しなかったため、AdoConnection1.RollbackTrans の実行中にエラーが発生しました。
正しいコード: =============================================== ================================================
AdoConnection1.BeginTrans;
試す
...
...
AdoConnection1.CommitTrans;
を除外する
AdoConnection1.RollbackTrans;
終わり;
================================================= =============================================
つまり、try の構造は異常な操作を保護するために使用されており、try...excel の間に例外が発生した場合は、excel...end 間の操作が実行されます。建築の。
4. 自分自身の取引保護を詐取する行為
データベースアプリケーションソフトウェアを作成する場合、元のデータを判断し、それに応じて修正を加えるという問題に遭遇することがよくあります。この問題は比較的単純に見えますが、ネットワーク上に同じシステムを使用している他の人がいることを考慮すると、偶発的な変更の可能性を考慮する必要があります。私の同僚は不注意で、私の指示の後、マルチユーザーの問題を考慮しましたが、それでも問題のあるコードを書きました。
================================================= =============================================
変数
adsTemp: TAdoDataSet;
isOk: ブール値;
始める
adsTemp := TAdoDataSet.Create(self);
試す
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'fid=120 の tb1 から fid、fnumber を選択';
adsTemp.Open;
isOk := adsTemp.FieldByName('fnumber').AsInteger>100;
ついに
広告一時無料。
終わり;
そうでない場合はOKです
出口;
AdoConnection1.BeginTrans;
試す
AdoConnection1.Execute('update tb1 set ffull=ffull + 1 from tb1 where fid=120';
...
...
AdoConnection1.CommitTrans;
を除外する
AdoConnection1.RollbackTrans;
終わり;
終わり;
================================================= =============================================
分析: AdoConnection1.BeginTrans の前にデータが判定され、データが共有されている場合、判定後から判定前までの間に AdoConnection1.Execute が使用されます。 AdoConnection1.BeginTrans, tb1 データが変更された可能性があるため、このトランザクション保護は役に立ちません。
正しい方法は、判定と変更が同じデータである必要があることです。次の例は 2 つの方法を示しています (違いは、トランザクションが開始される場所が異なることです)。
コード 1 (トランザクション保護を使用した後、同じデータが判定および変更される):
================================================= =============================================
変数
adsTemp: TAdoDataSet;
isOk: ブール値;
始める
AdoConnection1.BeginTrans;
試す
adsTemp := TAdoDataSet.Create(self);
試す
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'fid=120 の tb1 から fid、fnumber、ffull を選択';
adsTemp.Open;
if adsTemp.FieldByName('fnumber').AsInteger>100 then
始める
adsTemp.編集;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
広告一時投稿;
終わり;
ついに
広告一時無料。
終わり;
AdoConnection1.CommitTrans;
を除外する
AdoConnection1.RollbackTrans;
終わり;
終わり;
================================================= =============================================
コード 2 (例外キャプチャを使用し、判定と変更が同じデータでない場合、adsTemp.Post 中に例外が発生します。これは ADODataSet オブジェクトの機能です):
================================================= =============================================
変数
adsTemp: TAdoDataSet;
isOk: ブール値;
始める
adsTemp := TAdoDataSet.Create(self);
試す
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'fid=120 の tb1 から fid、fnumber、ffull を選択';
adsTemp.Open;
if adsTemp.FieldByName('fnumber').AsInteger>100 then
始める
AdoConnection1.BeginTrans;
試す
adsTemp.編集;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
広告一時投稿;
AdoConnection1.CommitTrans;
を除外する
AdoConnection1.RollbackTrans;
終わり;
終わり;
ついに
広告一時無料。
終わり;
終わり;