00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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") :
00067 m_Name(TName) { }
00068
00070
00076 void operator()(TRANSACTION &T);
00077
00078
00079
00080
00081
00082
00083
00084
00086
00091 void OnAbort(const char[]) throw () {}
00092
00093
00095
00098 void OnCommit() {}
00099
00100
00102
00111 void OnDoubt() throw () {}
00112
00113
00115 PGSTD::string Name() const { return m_Name; }
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
00144
00145 do
00146 {
00147 --Attempts;
00148
00149
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
00161
00162 T2.OnDoubt();
00163 throw;
00164 }
00165 catch (const PGSTD::exception &e)
00166 {
00167
00168 T2.OnAbort(e.what());
00169 if (Attempts <= 0) throw;
00170 continue;
00171 }
00172 catch (...)
00173 {
00174
00175 T2.OnAbort("Unknown exception");
00176 throw;
00177 }
00178
00179 T2.OnCommit();
00180 } while (!Done);
00181 }
00182
00183