00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string>
00020
00021 #include "pqxx/compiler.h"
00022 #include "pqxx/connection_base"
00023 #include "pqxx/transaction"
00024
00025
00026
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") :
00065 m_Name(TName) { }
00066
00068
00074 void operator()(TRANSACTION &T);
00075
00076
00077
00078
00079
00080
00081
00082
00084
00089 void OnAbort(const char[]) throw () {}
00090
00091
00093
00096 void OnCommit() {}
00097
00098
00100
00109 void OnDoubt() throw () {}
00110
00111
00113 PGSTD::string Name() const { return m_Name; }
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
00142
00143 do
00144 {
00145 --Attempts;
00146
00147
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
00159
00160 T2.OnDoubt();
00161 throw;
00162 }
00163 catch (const PGSTD::exception &e)
00164 {
00165
00166 T2.OnAbort(e.what());
00167 if (Attempts <= 0) throw;
00168 continue;
00169 }
00170 catch (...)
00171 {
00172
00173 T2.OnAbort("Unknown exception");
00174 throw;
00175 }
00176
00177 T2.OnCommit();
00178 } while (!Done);
00179 }
00180
00181