transactor.hxx
/*-------------------------------------------------------------------------
*
* FILE
* pqxx/transactor.hxx
*
* DESCRIPTION
* definition of the pqxx::transactor class.
* pqxx::transactor is a framework-style wrapper for safe transactions
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead.
*
* Copyright (c) 2001-2008, Jeroen T. Vermeulen <jtv@xs4all.nl>
*
* See COPYING for copyright license. If you did not receive a file called
* COPYING with this source code, please notify the distributor of this mistake,
* or contact the author.
*
*-------------------------------------------------------------------------
*/
#ifndef PQXX_H_TRANSACTOR
#define PQXX_H_TRANSACTOR
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include "pqxx/connection_base"
#include "pqxx/transaction"
/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
*/
namespace pqxx
{
template<typename TRANSACTION=transaction<read_committed> >
class transactor :
public PGSTD::unary_function<TRANSACTION, void>
{
public:
explicit transactor(const PGSTD::string &TName="transactor") : //[t4]
m_Name(TName) { }
void operator()(TRANSACTION &T); //[t4]
// Overridable member functions, called by connection_base::perform() if an
// attempt to run transaction fails/succeeds, respectively, or if the
// connection is lost at just the wrong moment, goes into an indeterminate
// state. Use these to patch up runtime state to match events, if needed, or
// to report failure conditions.
void on_abort(const char[]) throw () {} //[t13]
void on_commit() {} //[t7]
void on_doubt() throw () {} //[t13]
// TODO: Rename Name()--is there a compatible way?
PGSTD::string Name() const { return m_Name; } //[t13]
private:
PGSTD::string m_Name;
};
}
template<typename TRANSACTOR>
inline void pqxx::connection_base::perform(const TRANSACTOR &T,
int Attempts)
{
if (Attempts <= 0) return;
bool Done = false;
// Make attempts to perform T
// TODO: Differentiate between db-related exceptions and other exceptions?
do
{
--Attempts;
// Work on a copy of T2 so we can restore the starting situation if need be
TRANSACTOR T2(T);
try
{
typename TRANSACTOR::argument_type X(*this, T2.Name());
T2(X);
X.commit();
Done = true;
}
catch (const in_doubt_error &)
{
// Not sure whether transaction went through or not. The last thing in
// the world that we should do now is retry.
T2.on_doubt();
throw;
}
catch (const PGSTD::exception &e)
{
// Could be any kind of error.
T2.on_abort(e.what());
if (Attempts <= 0) throw;
continue;
}
catch (...)
{
// Don't try to forge ahead if we don't even know what happened
T2.on_abort("Unknown exception");
throw;
}
T2.on_commit();
} while (!Done);
}
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::transactor::Name
std::string Name() const
The transactor&#39;s name.
Definition: transactor.hxx:127
pqxx::transactor::on_doubt
void on_doubt()
Overridable function to be called when "in doubt" about outcome.
Definition: transactor.hxx:123
pqxx::in_doubt_error
"Help, I don&#39;t know whether transaction was committed successfully!"
Definition: except.hxx:156
pqxx::transactor
Definition: transactor.hxx:66
pqxx::transactor::operator()
void operator()(TRANSACTION &T)
Overridable transaction definition; insert your database code here.
pqxx::transactor::on_commit
void on_commit()
Optional overridable function to be called after successful commit.
Definition: transactor.hxx:109
pqxx::connection_base::perform
void perform(const TRANSACTOR &T, int Attempts)
Perform the transaction defined by a transactor-based object.
Definition: transactor.hxx:138
pqxx::transactor::transactor
transactor(const std::string &TName="transactor")
Definition: transactor.hxx:70
pqxx::transactor::on_abort
void on_abort(const char[])
Optional overridable function to be called if transaction is aborted.
Definition: transactor.hxx:102
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: basic_connection.hxx:35