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