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
00060 template<typename TRANSACTION=transaction<read_committed> >
00061 class transactor :
00062 public PGSTD::unary_function<TRANSACTION, void>
00063 {
00064 public:
00065 explicit transactor(const PGSTD::string &TName="transactor") :
00066 m_Name(TName) { }
00067
00069
00075 void operator()(TRANSACTION &T);
00076
00077
00078
00079
00080
00081
00082
00083
00085
00090 void OnAbort(const char[]) throw () {}
00091
00092
00094
00097 void OnCommit() {}
00098
00099
00101
00110 void OnDoubt() throw () {}
00111
00112
00114 PGSTD::string Name() const { return m_Name; }
00115
00116 private:
00117 PGSTD::string m_Name;
00118 };
00119
00120
00121 }
00122
00123
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.OnDoubt();
00162 throw;
00163 }
00164 catch (const PGSTD::exception &e)
00165 {
00166
00167 T2.OnAbort(e.what());
00168 if (Attempts <= 0) throw;
00169 continue;
00170 }
00171 catch (...)
00172 {
00173
00174 T2.OnAbort("Unknown exception");
00175 throw;
00176 }
00177
00178 T2.OnCommit();
00179 } while (!Done);
00180 }
00181
00182