Pergunta: Escrevi uma classe de operação de banco de dados TDBPerate_DL para unificar as operações no banco de dados. Métodos para declarar o início da transação, confirmar a transação e reverter a transação são fornecidos para outras classes chamarem. TDBOperate_DL = class PRivate ADOC:TADOConnection; ADOQ:TADOQuery; isDestroyADOC:Boolean; fIsInTrans:Boolean; //Se a transação foi iniciada public isCommit:Boolean; //Se a transação deve ser confirmada, o padrão é verdadeiro, se uma classe votar contra o envio, é falso function IsInTrans:Boolean constructor Create(const newADOC: TADOConnection );sobrecarga; construtor Create(const ServerName,DataBaseName,UserID,PassWord:String);sobrecarga;destruidor Destruir;substituir procedimento BeginTrans; CommitTrans; procedimento RollbackTrans; procedimento Execute(const sqlString:String); função GetDataset(const sqlString:String):_Recordset função GetConnection:TADOConnection procedimento SetConnection(const newADOC:TADOConnection end); ; //Iniciar transação start self.ADOC.BeginTrans; self.fIsInTrans := true;end;procedure TDBOperate_DL.CommitTrans; //Commit transação começa self.ADOC.CommitTrans := false;end;procedure TDBOperate_DL.RollbackTrans ; self.fIsInTrans := false;end;função TDBPerate_DL.IsInTrans: Boolean; //Verifique se a transação foi iniciada start result := self.fIsInTrans;end;Escreva uma classe TThing para adicionar, modificar ou excluir registros sobre algo no banco de dados, chame a classe TDBPerate_DL para concluir. Para maior comodidade da chamada, as transações relevantes são colocadas na classe TThing, não havendo necessidade de considerar a transação ao fazer chamadas externas. Por exemplo: procedimento Tthing.Drop(const thing:String);var sqlString:String;begin sqlString := instrução SQL excluída; // DBOperate é uma variável privada do tipo TDBPerate_DL, passada ao criar um Tthing; parâmetros de instância de classe. tente self.DBOperate.Execute(sqlString); self.DBOperate.CommitTrans; exceto self.DBOperate.RollbackTrans; raise end;end; Mais tarde, escrevi uma classe TPerson para adicionar, modificar ou excluir informações sobre pessoas no banco de dados Record. A mesma transação é colocada na classe TPerson. Agora, quando quero excluir o registro de uma pessoa, chamo a classe TThing para excluir coisas relacionadas à pessoa. Se você excluir o TThing primeiro e depois declarar novamente a transação para excluir o TPerson, se o TPerson cometer um erro, como você poderá reverter o TThing? Por exemplo: procedimento Tperson.Drop(const person:String);var sqlString:String; thing:Tthing;begin sqlString := instrução SQL excluída := Tthing.Create(self.DBOperate); é passado como parâmetro. Self.DBOperate.BeginTrans; Try Thing.Drop(person); //Há uma transação dentro, veja o código acima Self.DBOperate.Execute(sqlString); fim;fim ;Solução, envio em duas fases, primeiro algum conhecimento prévio: Não importa o sistema de duas ou três camadas, o processamento da transação é realizado por meio do envio em duas fases. Na primeira fase, cada recurso/registro executado é gravado no ambiente de transação (TranscationContext) e, em seguida, o coordenador de recursos consulta sequencialmente se a execução de cada transação participante foi bem-sucedida. Se não houver problemas, ele entra na segunda fase. a execução começa com o commit de suas operações. Se houver um problema com uma execução, o coordenador de recursos notificará todas as execuções subordinadas para desistirem do commit e restaurarem o estado original dos dados. Referindo-se à operação de transação do COM+, se um componente requer uma transação, a transação já foi iniciada quando o componente é criado. Quando o componente é destruído, uma votação de transação é executada. Se for uma transação raiz, a transação é confirmada ou. revertido. (Se o componente suportar pooling, essas duas situações ocorrerão na ativação do componente e nos eventos de suspensão). Portanto, definimos uma classe da seguinte maneira. //Classe ancestral da classe de negócios, usada para fornecer suporte a transações unificadas TTS_DL = class private isRootTrans:Boolean; //Se é uma transação raiz isNeedTrans:Boolean; //Se uma transação é necessária public DBOperate:TDBOperate_DL; opera o procedimento de instância do banco de dados SetComplete; procedimento SetAbort construtor Create(const newDBOperate:TDBOperate_DL; needTrans:Boolean);//Se o destruidor de suporte à transação é necessário Destroy; override; end Quando esta classe é criada, além de passar a instância da classe que opera o banco de dados, é passado um flag para indicar se uma transação é necessária, pois se trata apenas de uma operação de leitura do banco de dados. banco de dados, não há necessidade de uma transação. O código de implementação da classe é o seguinte: construtor TTS_DL.Create(const newDBOperate: TDBOperate_DL; needTrans: Boolean);begin herdado Create;= newDBOperate; .isNeedTrans então começa //Se estiver em uma transação, não é a transação raiz e o valor de isCommit no contexto da transação permanece inalterado se self.DBOperate.isInTrans then self.isRootTrans := false else start self.DBOperate.BeginTrans := true; Inicialize o sinalizador de commit Para confirmar a transação end;end;destructor TTS_DL.Destroy;begin se self.isNeedTrans então comece //Se for uma transação raiz, confirme ou reverta a transação de acordo com os resultados da votação if self.isRootTrans then start if self.DBOperate.isCommit then self.DBOperate.CommitTrans else self.DBOperate.RollbackTrans herdado end; fim do procedimento TTS_DL.SetAbort; início self.DBOperate.isCommit := self.DBOperate.isCommit E falso; //Vote no rollbackend;procedimento TTS_DL.SetComplete;begin self.DBOperate.isCommit := self.DBOperate.isCommit And true; //Vote no commitend;Volte para as classes de negócio Tthing e Tperson, desta vez Todas são herdadas do Classe TTS_DL. Tthing = class(TTS_DL); Tperson = class(TTS_DL); O código de exclusão de Tthing deve ser o seguinte: procedimento Tthing.Drop(const thing:String);var sqlString:String;begin sqlString := instrução SQL excluída; .DBOperate.Execute(sqlString); self.DBOperate.SetComplete; DBOperate.SetAbort; //Vote rollback raise; end;end; o código de exclusão de Tperson é o seguinte: procedimento Tperson.Drop(const person:String);var sqlString:String;begin sqlString := instrução SQL excluída; := Tthing.Create(self.DBOperate,true); //Tipo TDBOperate_DL DBOperate é passado como parâmetro, true significa que uma transação é necessária. Try Try Thing.Drop(person); Self.DBOperate.Execute(sqlString); self.DBOperate.SetComplete; //Submissão de voto exceto self. //Lembre-se de liberar end;end; Lembre-se de manter a única instância da classe de banco de dados operacional TDBOperate_DL usada no programa e lembre-se de liberar a instância da classe de negócios. Se uma transação for necessária, libere-a o mais cedo possível, OK, feito. A primeira versão tem um nível limitado e precisa ser melhorada em aplicações práticas. É apenas uma forma de atrair novas ideias. Por favor, tenha heróis experientes para contribuir.