六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

用Delphi模擬組件的2階段提交

[摘要]問題提出:寫了一個數據庫操作的類TDBOperate_DL,統一對數據庫的操作嘛。提供了聲明事務開始、提交事務和回滾事務的方法供其他類調用。TDBOperate_DL = class private ADOC:TADOConnection; ADOQ:TADOQuery; is...
問題提出:寫了一個數據庫操作的類TDBOperate_DL,統一對數據庫的操作嘛。提供了聲明事務開始、提交事務和回滾事務的方法供其他類調用。

TDBOperate_DL = class

  private

    ADOC:TADOConnection;

    ADOQ:TADOQuery;

    isDestroyADOC:Boolean;    //是否銷毀自己的ADOC?

    fIsInTrans:Boolean;        //是否已經開始事務

  public

    isCommit:Boolean;         //是否要提交事務,缺省是真,如果有類投票說反對提交,就為假

    function IsInTrans:Boolean;

    constructor Create(const newADOC:TADOConnection);overload;

    constructor Create(const ServerName,DataBaseName,UserID,Password:String);overload;

    destructor Destroy;override;

    procedure BeginTrans;

    procedure CommitTrans;

    procedure RollbackTrans;

    procedure Execute(const sqlString:String);

    function GetDataset(const sqlString:String):_Recordset;

    function GetConnection:TADOConnection;

    procedure SetConnection(const newADOC:TADOConnection);

  end;

       一些函數的實現:

procedure TDBOperate_DL.BeginTrans;          //開始事務

begin

  self.ADOC.BeginTrans;

  self.fIsInTrans := true;

end;



procedure TDBOperate_DL.CommitTrans;              //提交事務

begin

  self.ADOC.CommitTrans;

  self.fIsInTrans := false;

end;



procedure TDBOperate_DL.RollbackTrans;              //回滾事務

begin

  self.ADOC.RollbackTrans;

  self.fIsInTrans := false;

end;



function TDBOperate_DL.IsInTrans: Boolean;         //查看事務是否已開始

begin

  result := self.fIsInTrans;

end;



寫了一個TThing類,用于向數據庫中添加、修改或刪除有關某種東西的記錄,調用TDBOperate_DL類完成。為了調用方便,因此有關的事務就放在了TThing類中,外部調用時不用考慮事務了。

如:

procedure Tthing.Drop(const thing:String);

var

  sqlString:String;

begin

  sqlString := 刪除的SQL語句;

  self.DBOperate.BeginTrans;           // DBOperate是TDBOperate_DL類型的私有變量,創建Tthing類實例時傳入的參數。

  try

    self.DBOperate.Execute(sqlString);

    self.DBOperate.CommitTrans;

  except

    self. DBOperate.RollbackTrans;

    raise;

  end;

end;

后來又寫了個TPerson類,用于向數據庫中添加、修改或刪除有關人的記錄。同樣事務放在了TPerson類中,現在我想刪除人的記錄時順便調用TThing類刪除和人有關的東西,事務問題就出現啦:事務不能嵌套啊。如果先刪除TThing,再重新聲明事務刪除TPerson,如果TPerson出錯,還怎么回滾TThing?

如:

procedure Tperson.Drop(const person:String);

var

  sqlString:String;

  thing:Tthing;

begin

  sqlString := 刪除的SQL語句;

  thing := Tthing.Create(self.DBOperate);              //TDBOperate_DL類型的DBOperate是作為參數傳進去的。

  Self.DBOperate.BeginTrans;

  Try

    Thing.Drop(person);               //里面有事務見上面的代碼

    Self.DBOperate.Execute(sqlString);

    self.DBOperate.CommitTrans;

  except

    self.DBOperate.RollbackTrans;

    raise;

  end;

end;

解決方法,兩階段提交,先粘點背景知識:

不論兩層或三層體系,事物處理都是通過兩階段提交實現的。在第一階段,每個執行的的資源\記錄被寫入 事物環境(Transcation Context)中,然后資源協調者順序查詢每一個參與事物的執行是否成功,如果都沒有問題的話,就進入第二階段,每個執行都開始Commit它的操作。如果有一個執行有問題的話,資源協調者通知所有下屬的執行放棄Commit,恢復數據原狀態。

參考COM+的事務運行,如果一個組件是需要事務的,那么在組件創建時,事務就已經開始了,在組件銷毀時進行事務投票,如果是根事務,則進行提交或回滾事務。(如果組件支持池化,這兩種情況發生在組件激活和休眠事件中)。于是我們定義一個類如下。

//業務類的祖先類,用于提供統一的事務支持

  TTS_DL = class

  private

    isRootTrans:Boolean;      //是否是根事務

    isNeedTrans:Boolean;      //是否需要事務

  public

    DBOperate:TDBOperate_DL;   //操作數據庫的類的實例

    procedure SetComplete;

    procedure SetAbort;

    constructor Create(const newDBOperate:TDBOperate_DL;needTrans:Boolean);//是否需要事務支持

    destructor Destroy;override;

  end;

在該類創建時,除了傳遞進操作數據庫的類的實例外,再傳入一個是否需要事務的標志,因為如果是只做讀取數據庫的操作,就用不著事務了。

類實現代碼如下:

constructor TTS_DL.Create(const newDBOperate: TDBOperate_DL;

  needTrans: Boolean);

begin

  inherited Create;

  self.DBOperate := newDBOperate;              

  self.isNeedTrans := needTrans;                     //賦值是否需要事務

  if self.isNeedTrans then

  begin

    //如果在事務里,就不是根事務,保留事務上下文里isCommit的值不變

    if self.DBOperate.isInTrans then

      self.isRootTrans := false

    else

    begin

      self.DBOperate.BeginTrans;           //是根事務,就開始事務

      self.isRootTrans := true;

      self.DBOperate.isCommit := true;       //初始化提交標志為要提交事務

    end;

  end;

end;



destructor TTS_DL.Destroy;

begin

  if self.isNeedTrans then

  begin

    //如果是根事務,就按照投票結果進行事務提交或回滾

    if self.isRootTrans then

    begin

      if self.DBOperate.isCommit then

        self.DBOperate.CommitTrans

      else

        self.DBOperate.RollbackTrans;

    end;

  end;

  inherited;

end;



procedure TTS_DL.SetAbort;

begin

  self.DBOperate.isCommit := self.DBOperate.isCommit And false;       //投票說要回滾

end;



procedure TTS_DL.SetComplete;

begin

  self.DBOperate.isCommit := self.DBOperate.isCommit And true; //投票說要提交

end;



回到剛才的業務類Tthing和Tperson,這次都從TTS_DL類繼承下來。

       Tthing = class(TTS_DL);

       Tperson = class(TTS_DL);

Tthing的刪除代碼該為如下:

procedure Tthing.Drop(const thing:String);

var

  sqlString:String;

begin

  sqlString := 刪除的SQL語句;

  try

    self. DBOperate.Execute(sqlString);

    self. DBOperate.SetComplete;         //投票提交

  except

    self. DBOperate.SetAbort;                     //投票回滾

    raise;

  end;

end;

Tperson的刪除代碼如下:

procedure Tperson.Drop(const person:String);

var

  sqlString:String;

  thing:Tthing;

begin

  sqlString := 刪除的SQL語句;

  thing := Tthing.Create(self. DBOperate,true);              //TDBOperate_DL類型的DBOperate是作為參數傳進去的,true代表需要事務。

  Try

    Try

      Thing.Drop(person);

      Self.DBOperate.Execute(sqlString);

      self.DBOperate.SetComplete;           //投票提交

    except

      self. DBOperate.SetAbort;                       //投票回滾

      raise;

    end;

  finally

    thing.free;                                                           //記著一定要釋放

  end;

end;

記著保持程序中使用唯一的操作數據庫類TDBOperate_DL的實例,記著釋放業務類實例,如果是需要事務的,盡量早釋放,OK,搞定。

第一個版本,水平有限,還需要在實際應用中完善,全當拋磚引玉,請有經驗的大俠們拍磚吧:)


主站蜘蛛池模板: 在线另类| 亚州一级毛片在线 | 日本爱爱视频 | 英国美女一级毛片视频 | 青春草在线观看 | 亚洲国产一 | 日本欧美一区 | 天天操婷婷 | 天天爱天天操 | 日韩视频二区 | 青青草华人在线 | 亚洲女人在线 | 中文字幕视频一区二区 | 中文字幕第35页 | 一级做a爰片久久毛片一 | 色噜噜狠狠色综合免费视频 | 日本全黄视频 | 中文字幕不卡视频 | 午夜精品福利影院 | 四虎在线永久精品高清 | 午夜欧美福利视频 | 亚洲免费在线视频观看 | 午夜激情影视 | 亚洲欧美日韩不卡一区二区三区 | 四虎影永久在线观看精品 | 婷婷中文网 | 人人干人人看 | 亚洲欧美综合久久 | 亚洲成av人片天堂网 | 欧美性操 | 欧美亚洲另类一区中文字幕 | 午夜免费网站 | 天美蜜桃精东乌鸦果冻麻豆 | 日韩精品一区二区三区中文精品 | 日韩精品亚洲精品485页 | 在线亚洲天堂 | 欧美视频福利 | 午夜毛片视频 | 欧美做真爱欧美观看免费 | 亚洲www视频 | 校园激情综合网 |