00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/connection_base"
00020 #include "pqxx/transaction"
00021
00022
00023
00024
00025
00027 #define PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00028
00029 namespace pqxx
00030 {
00031
00033
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
00079 void operator()(TRANSACTION &T);
00080
00081
00082
00083
00084
00085
00086
00088
00096 void on_abort(const char[]) throw () {}
00097
00099
00103 void on_commit() {}
00104
00106
00117 void on_doubt() throw () {}
00118
00119 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00120
00121
00122 void OnCommit() {}
00124
00125 void OnAbort(const char[]) throw () {}
00127
00128 void OnDoubt() throw () {}
00129 #endif
00130
00131
00133 PGSTD::string Name() const { return m_Name; }
00134
00135 private:
00136 PGSTD::string m_Name;
00137 };
00138
00139
00140 }
00141
00142
00153 template<typename TRANSACTOR>
00154 inline void pqxx::connection_base::perform(const TRANSACTOR &T,
00155 int Attempts)
00156 {
00157 if (Attempts <= 0) return;
00158
00159 bool Done = false;
00160
00161
00162
00163 do
00164 {
00165 --Attempts;
00166
00167
00168 TRANSACTOR T2(T);
00169 try
00170 {
00171 typename TRANSACTOR::argument_type X(*this, T2.Name());
00172 T2(X);
00173 X.commit();
00174 Done = true;
00175 }
00176 catch (const in_doubt_error &)
00177 {
00178
00179
00180 T2.OnDoubt();
00181 throw;
00182 }
00183 catch (const PGSTD::exception &e)
00184 {
00185
00186 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00187 T2.OnAbort(e.what());
00188 #endif
00189 T2.on_abort(e.what());
00190 if (Attempts <= 0) throw;
00191 continue;
00192 }
00193 catch (...)
00194 {
00195
00196 T2.OnAbort("Unknown exception");
00197 throw;
00198 }
00199
00200 #ifdef PQXX_DEPRECATED_TRANSACTION_CALLBACKS
00201 T2.OnCommit();
00202 #endif
00203 T2.on_commit();
00204 } while (!Done);
00205 }
00206
00207