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 Sat Aug 21 03:39:32 2004 for libpqxx by doxygen 1.3.8