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