Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | 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-2005, 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/connection_base"
00020 #include "pqxx/transaction"
00021 
00022 
00023 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00024  */
00025 
00027 #define PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00028 
00029 namespace pqxx
00030 {
00031 
00033 
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 
00079   void operator()(TRANSACTION &T);                                      //[t4]
00080 
00081   // Overridable member functions, called by connection_base::perform() if an
00082   // attempt to run transaction fails/succeeds, respectively, or if the 
00083   // connection is lost at just the wrong moment, goes into an indeterminate 
00084   // state.  Use these to patch up runtime state to match events, if needed, or
00085   // to report failure conditions.
00086 
00088 
00096   void on_abort(const char[]) throw () {}                               //[t13]
00097 
00099 
00103   void on_commit() {}                                                   //[t6]
00104 
00106 
00117   void on_doubt() throw () {}                                           //[t13]
00118 
00119 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00120 
00121 
00122   void OnCommit() {}
00124 
00125   void OnAbort(const char[]) throw () {}
00127 
00128   void OnDoubt() throw () {}
00129 #endif
00130 
00131   // TODO: Rename Name()--is there a compatible way?
00133   PGSTD::string Name() const { return m_Name; }                         //[t13]
00134 
00135 private:
00136   PGSTD::string m_Name;
00137 };
00138 
00139 
00140 }
00141 
00142 
00153 template<typename TRANSACTOR> 
00154 inline void pqxx::connection_base::perform(const TRANSACTOR &T,
00155                                            int Attempts)
00156 {
00157   if (Attempts <= 0) return;
00158 
00159   bool Done = false;
00160 
00161   // Make attempts to perform T
00162   // TODO: Differentiate between db-related exceptions and other exceptions?
00163   do
00164   {
00165     --Attempts;
00166 
00167     // Work on a copy of T2 so we can restore the starting situation if need be
00168     TRANSACTOR T2(T);
00169     try
00170     {
00171       typename TRANSACTOR::argument_type X(*this, T2.Name());
00172       T2(X);
00173       X.commit();
00174       Done = true;
00175     }
00176     catch (const in_doubt_error &)
00177     {
00178       // Not sure whether transaction went through or not.  The last thing in
00179       // the world that we should do now is retry.
00180       T2.OnDoubt();
00181       throw;
00182     }
00183     catch (const PGSTD::exception &e)
00184     {
00185       // Could be any kind of error.  
00186 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00187       T2.OnAbort(e.what());
00188 #endif
00189       T2.on_abort(e.what());
00190       if (Attempts <= 0) throw;
00191       continue;
00192     }
00193     catch (...)
00194     {
00195       // Don't try to forge ahead if we don't even know what happened
00196       T2.OnAbort("Unknown exception");
00197       throw;
00198     }
00199 
00200 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00201     T2.OnCommit();
00202 #endif
00203     T2.on_commit();
00204   } while (!Done);
00205 }
00206 
00207 

Generated on Tue Feb 8 09:17:14 2005 for libpqxx by  doxygen 1.4.1