Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

transactor.h

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

Generated on Sat Jun 7 00:49:34 2003 for libpqxx by doxygen1.3-rc3