질문: 데이터베이스 작업을 통합하기 위해 데이터베이스 작업 클래스 TDBPerate_DL을 작성했습니다. 다른 클래스가 호출할 수 있도록 트랜잭션 시작 선언, 트랜잭션 커밋, 트랜잭션 롤백 방법을 제공합니다. TDBOperate_DL = class PRivate ADOC:TADOConnection; ADOQ:TADOQuery; isDestroyADOC:Boolean; fIsInTrans:Boolean; //트랜잭션이 시작되었는지 여부 public isCommit:Boolean; //트랜잭션을 커밋할지 여부, 기본값은 true, 클래스가 제출에 반대하는 경우 false function IsInTrans:Boolean constructor Create(const newADOC: TADOConnection );overload; 생성자 Create(const ServerName,DataBaseName,UserID,PassWord:String);destroy;override 절차; CommitTrans; 프로시저 Execute(const sqlString:String):_Recordset; function GetConnection:TADOConnection(const newADOC:TADOConnection) end; ; //트랜잭션 시작 start self.ADOC.BeginTrans; self.fIsInTrans := true;end;procedure TDBOperate_DL.CommitTrans; //커밋 트랜잭션 시작 self.ADOC.CommitTrans; self.fIsInTrans := false;end;procedure TDBOperate_DL.RollbackTrans; //롤백 트랜잭션 시작 self.ADOC.RollbackTrans; self.fIsInTrans := false;end;function TDBPerate_DL.IsInTrans: 부울; //트랜잭션이 시작되었는지 확인합니다. start result := self.fIsInTrans;end; 데이터베이스에 대한 레코드를 추가, 수정 또는 삭제하려면 TThing 클래스를 작성하고 TDBPerate_DL 클래스를 호출하여 완료합니다. 호출의 편의를 위해 해당 트랜잭션은 TThing 클래스에 배치하며, 외부 호출 시 트랜잭션을 고려할 필요가 없습니다. 예를 들면 다음과 같습니다. 프로시저 Tthing.Drop(const thing:String);var sqlString:String;begin sqlString := 삭제된 SQL 문; self.DBPerate.BeginTrans; // DBOperate는 Tthing 생성 시 전달되는 TDBPerate_DL 유형의 전용 변수입니다. 클래스 인스턴스 매개변수. try self.DBOperate.Execute(sqlString); self.DBOperate.RollbackTrans; raise; end;end; 나중에 데이터베이스 레코드에 대한 정보를 추가, 수정 또는 삭제하기 위한 TPerson 클래스를 작성했습니다. 동일한 트랜잭션이 TPerson 클래스에 배치됩니다. 이제 개인의 기록을 삭제하려면 TThing 클래스를 호출하여 해당 개인과 관련된 항목을 삭제합니다. 트랜잭션을 중첩할 수 없습니다. TThing을 먼저 삭제한 후 TPerson을 삭제하기 위해 트랜잭션을 다시 선언하는 경우 TPerson에서 오류가 발생하면 어떻게 TThing을 롤백할 수 있나요? 예: 프로시저 Tperson.Drop(const person:String);var sqlString:String; thing:Tthing;begin sqlString := 삭제된 SQL 문; thing := Tthing.Create(self.DBOperate) //The DBOperate of TDBOperate_DL 매개변수로 전달됩니다. Self.DBOperate.BeginTrans; Thing.Drop(person); //내부에 트랜잭션이 있습니다. Self.DBOperate.Execute(sqlString); self.DBOperate.RollbackTrans; end;end ;솔루션, 2단계 제출, 먼저 몇 가지 배경 지식: 2계층 또는 3계층 시스템에 관계없이 트랜잭션 처리는 2단계 제출을 통해 실현됩니다. 첫 번째 단계에서는 실행된 각 리소스/레코드가 트랜잭션 환경(TranscationContext)에 기록되며, 리소스 코디네이터는 참여하는 각 트랜잭션의 실행이 성공했는지 순차적으로 쿼리하여 문제가 없으면 두 번째 단계로 진입합니다. 실행은 해당 작업을 커밋하여 시작됩니다. 하나의 실행에 문제가 있는 경우 리소스 코디네이터는 모든 하위 실행에 커밋을 포기하고 데이터의 원래 상태를 복원하도록 알립니다. COM+의 트랜잭션 동작을 참고하면, 컴포넌트가 트랜잭션을 필요로 하는 경우 컴포넌트가 생성될 때 트랜잭션이 이미 시작되었습니다. 컴포넌트가 소멸되면 트랜잭션 투표가 수행됩니다. 루트 트랜잭션이면 해당 트랜잭션이 커밋됩니다. 롤백되었습니다. (구성 요소가 풀링을 지원하는 경우 구성 요소 활성화 및 절전 이벤트에서 이 두 가지 상황이 발생합니다.) 그래서 우리는 클래스를 다음과 같이 정의합니다. //통합 트랜잭션 지원을 제공하는 데 사용되는 비즈니스 클래스의 상위 클래스 TTS_DL = class private isRootTrans:Boolean; //루트 트랜잭션인지 여부 isNeedTrans:Boolean; //트랜잭션이 필요한지 여부 public DBOperate:TDBOperate_DL; 데이터베이스 인스턴스 프로시저 SetComplete; 프로시저 SetAbort; 생성자 Create(const newDBOperate:TDBOperate_DL; needTrans:Boolean);//트랜잭션 지원 소멸자가 필요한지 여부 Destroy; override; end; 이 클래스가 생성되면 데이터베이스를 작동하는 클래스의 인스턴스를 전달하는 것 외에도 트랜잭션이 필요한지 여부를 결정하는 플래그가 전달됩니다. , 거래가 필요하지 않습니다. 클래스 구현 코드는 다음과 같습니다. constructor TTS_DL.Create(const newDBOperate: TDBOperate_DL; needTrans: Boolean);begin received Create; self.DBOperate := newDBOperate; self.isNeedTrans := needTrans; if self.isNeedTrans then start //트랜잭션에 있는 경우 루트 트랜잭션이 아니며 트랜잭션 컨텍스트의 isCommit 값은 변경되지 않고 유지됩니다. self.DBOperate.isInTrans then self.isRootTrans := false else start self.DBOperate.BeginTrans; //루트 트랜잭션인 경우 트랜잭션을 시작합니다. self.isRootTrans := true; 커밋 플래그 초기화 트랜잭션을 커밋하려면 end;end;destructor TTS_DL.Destroy;begin if self.isNeedTrans then start //루트 트랜잭션인 경우 투표 결과에 따라 트랜잭션을 커밋하거나 롤백합니다. if self.isRootTrans then start if self.DBOperate.isCommit then self.DBOperate.CommitTrans else self.DBOperate.RollbackTransherent; end; 절차 TTS_DL.SetAbort;begin self.DBOperate.isCommit := self.DBOperate.isCommit 그리고 false; //rollbackend에 투표;procedure TTS_DL.SetComplete;begin self.DBOperate.isCommit := self.DBOperate.isCommit And true; //commit에 투표end; 비즈니스 클래스 Tthing 및 Tperson으로 돌아가서 이번에는 모두 상속됩니다. TTS_DL 클래스. Tthing = class(TTS_DL); Tperson = class(TTS_DL); Tthing의 삭제 코드는 다음과 같아야 합니다. . DBOperate.Execute(sqlString); self.DBOperate.SetComplete; //자신을 제외한 투표 제출. DBOperate.SetAbort; //Vote 롤백 raise; end;end; Tperson의 삭제 코드는 다음과 같습니다. Procedure Tperson.Drop(const person:String);var sqlString:String := 삭제된 SQL 문 ; 물건 := Tthing.Create(self.DBOperate,true); //TDBOperate_DL 유형 DBOperate가 매개변수로 전달됩니다. true는 트랜잭션이 필요함을 의미합니다. Thing.Drop(person); Self.DBOperate.SetComplete; //자체를 제외한 투표 제출 //마지막으로 thing.free; //해제하는 것을 기억하세요. end; 프로그램에 사용되는 운영 데이터베이스 클래스 TDBOperate_DL의 유일한 인스턴스를 유지하고, 비즈니스 클래스 인스턴스를 해제하는 것을 기억하세요. 트랜잭션이 필요한 경우 최대한 빨리 해제하세요. 완료. 첫 번째 버전은 레벨이 제한되어 있어 실제 적용 시 개선이 필요합니다. 이는 새로운 아이디어를 끌어내기 위한 방법일 뿐입니다. 경험이 풍부한 영웅들이 기여해 주시기 바랍니다.