00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/compiler-public.hxx"
00020 #include "pqxx/compiler-internal-pre.hxx"
00021
00022 #include "pqxx/connection_base"
00023 #include "pqxx/transaction"
00024
00025
00026
00027
00028
00029 namespace pqxx
00030 {
00031
00033
00062 template<typename TRANSACTION=transaction<read_committed> >
00063 class transactor :
00064 public PGSTD::unary_function<TRANSACTION, void>
00065 {
00066 public:
00067 explicit transactor(const PGSTD::string &TName="transactor") :
00068 m_Name(TName) { }
00069
00071
00082 void operator()(TRANSACTION &T);
00083
00084
00085
00086
00087
00088
00089
00091
00099 void on_abort(const char[]) throw () {}
00100
00102
00106 void on_commit() {}
00107
00109
00120 void on_doubt() throw () {}
00121
00122
00124 PGSTD::string Name() const { return m_Name; }
00125
00126 private:
00127 PGSTD::string m_Name;
00128 };
00129
00130
00131 }
00132
00133
00134 template<typename TRANSACTOR>
00135 inline void pqxx::connection_base::perform(const TRANSACTOR &T,
00136 int Attempts)
00137 {
00138 if (Attempts <= 0) return;
00139
00140 bool Done = false;
00141
00142
00143
00144 do
00145 {
00146 --Attempts;
00147
00148
00149 TRANSACTOR T2(T);
00150 try
00151 {
00152 typename TRANSACTOR::argument_type X(*this, T2.Name());
00153 T2(X);
00154 X.commit();
00155 Done = true;
00156 }
00157 catch (const in_doubt_error &)
00158 {
00159
00160
00161 T2.on_doubt();
00162 throw;
00163 }
00164 catch (const PGSTD::exception &e)
00165 {
00166
00167 T2.on_abort(e.what());
00168 if (Attempts <= 0) throw;
00169 continue;
00170 }
00171 catch (...)
00172 {
00173
00174 T2.on_abort("Unknown exception");
00175 throw;
00176 }
00177
00178 T2.on_commit();
00179 } while (!Done);
00180 }
00181
00182
00183 #include "pqxx/compiler-internal-post.hxx"