Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

transactor.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/transactor.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definition of the pqxx::transactor class.
00008  *   pqxx::transactor is a framework-style wrapper for safe transactions
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead.
00010  *
00011  * Copyright (c) 2001-2003, Jeroen T. Vermeulen <jtv@xs4all.nl>
00012  *
00013  * See COPYING for copyright license.  If you did not receive a file called
00014  * COPYING with this source code, please notify the distributor of this mistake,
00015  * or contact the author.
00016  *
00017  *-------------------------------------------------------------------------
00018  */
00019 #include <string>
00020 
00021 #include "pqxx/compiler.h"
00022 #include "pqxx/connection_base"
00023 #include "pqxx/transaction"
00024 
00025 
00026 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00027  */
00028 
00029 
00030 namespace pqxx
00031 {
00032 
00034 
00059 template<typename TRANSACTION=transaction<read_committed> > 
00060   class transactor : 
00061     public PGSTD::unary_function<TRANSACTION, void>
00062 {
00063 public:
00064   explicit transactor(const PGSTD::string &TName="transactor") :        //[t4]
00065     m_Name(TName) { }
00066 
00068 
00074   void operator()(TRANSACTION &T);                                      //[t4]
00075 
00076   // Overridable member functions, called by connection_base::Perform() if an
00077   // attempt to run transaction fails/succeeds, respectively, or if the 
00078   // connection is lost at just the wrong moment, goes into an indeterminate 
00079   // state.  Use these to patch up runtime state to match events, if needed, or
00080   // to report failure conditions.
00081 
00082   // TODO: Replace OnAbort()--is there a compatible way?
00084 
00089   void OnAbort(const char[]) throw () {}                                //[t13]
00090 
00091   // TODO: Replace OnCommit()--is there a compatible way?
00093 
00096   void OnCommit() {}                                                    //[t6]
00097 
00098   // TODO: Replace OnCommit()--is there a compatible way?
00100 
00109   void OnDoubt() throw () {}                                            //[t13]
00110 
00111   // TODO: Replace Name()--is there a compatible way?
00113   PGSTD::string Name() const { return m_Name; }                         //[t13]
00114 
00115 private:
00116   PGSTD::string m_Name;
00117 };
00118 
00119 
00120 }
00121 
00122 
00133 template<typename TRANSACTOR> 
00134 inline void pqxx::connection_base::perform(const TRANSACTOR &T,
00135                                            int Attempts)
00136 {
00137   if (Attempts <= 0) return;
00138 
00139   bool Done = false;
00140 
00141   // Make attempts to perform T
00142   // TODO: Differentiate between db-related exceptions and other exceptions?
00143   do
00144   {
00145     --Attempts;
00146 
00147     // Work on a copy of T2 so we can restore the starting situation if need be
00148     TRANSACTOR T2(T);
00149     try
00150     {
00151       typename TRANSACTOR::argument_type X(*this, T2.Name());
00152       T2(X);
00153       X.commit();
00154       Done = true;
00155     }
00156     catch (const in_doubt_error &)
00157     {
00158       // Not sure whether transaction went through or not.  The last thing in
00159       // the world that we should do now is retry.
00160       T2.OnDoubt();
00161       throw;
00162     }
00163     catch (const PGSTD::exception &e)
00164     {
00165       // Could be any kind of error.  
00166       T2.OnAbort(e.what());
00167       if (Attempts <= 0) throw;
00168       continue;
00169     }
00170     catch (...)
00171     {
00172       // Don't try to forge ahead if we don't even know what happened
00173       T2.OnAbort("Unknown exception");
00174       throw;
00175     }
00176 
00177     T2.OnCommit();
00178   } while (!Done);
00179 }
00180 
00181 

Generated on Sun Sep 21 01:09:24 2003 for libpqxx by doxygen 1.3.2