[BCB] ADO 交易模式

ADO Connection 的交易模式分享:     
int __fastcall BeginTrans(void);
Description:
Call BeginTrans to start a new transaction in the data store the ADO connection component is connected to.
BeginTrans returns a value of type integer, indicating the nesting level of the new transaction.
A successful execution of BeginTrans triggers an OnBeginTransComplete event and sets the InTransaction
property to true.
Note: The ADO connection object must have an active connection before BeginTrans can be used.

void __fastcall CommitTrans(void);
Description:
Call CommitTrans to save any changes made during the current transaction and to end the transaction.
A successful execution of CommitTrans triggers an OnCommitTransComplete event and sets the InTransaction
property to false.

void __fastcall RollbackTrans(void);
Description:
Call RollbackTrans to cancel any changes made during the current transaction and to end the transaction.
A successful execution of RollbackTrans triggers an OnRollbackTransComplete event and sets the InTransaction
property to true.
ADO 的交易模式預設是 auto commit,也就是每做一筆交易就馬上寫入資料庫,如果想要做批次寫入,
就必須使用 BeginTrans 函數。執行 BeginTrans 函數後,接下來的交易都不會被寫入資料庫,
必須等到 CommitTrans 函數執行才會寫入資料庫,並恢復 auto commit;
或是等到 RollbackTrans 函數執行,會取消此次所有交易,並恢復 auto commit。
而且 BeginTrans 可以套嵌使用,層層疊疊,但必須等到最後一個 CommitTrans 才會把所有交易寫入資料庫。
所以如果不小心執行 CommitTrans 卻沒有執行 CommitTrans 就結束程式,那就等著被人追殺吧。
■BeginTrans: 取消 auto commit,並設定還原點。
■CommitTrans: 寫入自還原點所有交易,恢復 auto commit。
■RollbackTrans: 取消自還原點所有交易,恢復 auto commit。
■BeginTrans 返回值表示第幾層套嵌,第一個執行 BeginTrans 返回 1,第二個執行 BeginTrans 返回 2,以此類推。
由於 BeginTrans 函數會造成資料庫沒有寫入的問題,當然這一定是個人寫程式那里有露掉沒檢查到的大 bug,
所以必須用寫一個預防機制放在 form close 裏。
void __fastcall TfrmMenu::FormClose(TObject *Sender, TCloseAction &Action)
{
    // 檢查 ADO connection transcation
    int count=0;
    while (1) {
        if (ADOConn->BeginTrans() == 1) break;
        ADOConn->CommitTrans();
        ADOConn->CommitTrans();
        count++;
    }
    ADOConn->CommitTrans();
    if (count > 0) {
        AnsiString msg;
        msg.printf("資料庫有未完成的交易共 %d 次。\n\n請通知系統人員處理。", count);
        MessageBox(GetActiveWindow(), msg.c_str(), "錯誤", MB_OK | MB_ICONSTOP);
    }
    ADOConn->Close();
}

留言