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

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-2004, 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 "pqxx/libcompiler.h"
00020 
00021 #include <string>
00022 
00023 #include "pqxx/connection_base"
00024 #include "pqxx/transaction"
00025 
00026 
00027 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00028  */
00029 
00030 
00031 namespace pqxx
00032 {
00033 
00035 
00061 template<typename TRANSACTION=transaction<read_committed> > 
00062   class 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 
00084   // TODO: Replace OnAbort()--is there a compatible way?
00086 
00091   void OnAbort(const char[]) throw () {}                                //[t13]
00092 
00093   // TODO: Replace OnCommit()--is there a compatible way?
00095 
00098   void OnCommit() {}                                                    //[t6]
00099 
00100   // TODO: Replace OnCommit()--is there a compatible way?
00102 
00111   void OnDoubt() throw () {}                                            //[t13]
00112 
00113   // TODO: Replace Name()--is there a compatible way?
00115   PGSTD::string Name() const { return m_Name; }                         //[t13]
00116 
00117 private:
00118   PGSTD::string m_Name;
00119 };
00120 
00121 
00122 }
00123 
00124 
00135 template<typename TRANSACTOR> 
00136 inline void pqxx::connection_base::perform(const TRANSACTOR &T,
00137                                            int Attempts)
00138 {
00139   if (Attempts <= 0) return;
00140 
00141   bool Done = false;
00142 
00143   // Make attempts to perform T
00144   // TODO: Differentiate between db-related exceptions and other exceptions?
00145   do
00146   {
00147     --Attempts;
00148 
00149     // Work on a copy of T2 so we can restore the starting situation if need be
00150     TRANSACTOR T2(T);
00151     try
00152     {
00153       typename TRANSACTOR::argument_type X(*this, T2.Name());
00154       T2(X);
00155       X.commit();
00156       Done = true;
00157     }
00158     catch (const in_doubt_error &)
00159     {
00160       // Not sure whether transaction went through or not.  The last thing in
00161       // the world that we should do now is retry.
00162       T2.OnDoubt();
00163       throw;
00164     }
00165     catch (const PGSTD::exception &e)
00166     {
00167       // Could be any kind of error.  
00168       T2.OnAbort(e.what());
00169       if (Attempts <= 0) throw;
00170       continue;
00171     }
00172     catch (...)
00173     {
00174       // Don't try to forge ahead if we don't even know what happened
00175       T2.OnAbort("Unknown exception");
00176       throw;
00177     }
00178 
00179     T2.OnCommit();
00180   } while (!Done);
00181 }
00182 
00183 

Generated on Mon May 10 13:19:09 2004 for libpqxx by doxygen 1.3.6-20040222