Writing database code can be tricky. One of the most complicated areas is dealing with unexpected error conditions, such as losing one's connection to the database server. For long-running processes you'll frequently find yourself rewriting code for a simple transaction to make it:
Attempt to perform the transaction.
Check for "connection lost" errors.
Attempt to restore the connection.
Repeat until the transaction succeeds.
	This is bad for the heart, and clutters up your code besides.  The
	transactor framework will take this work out of
	your hands if you let it.
      
The mechanism is based on the concept of Functors, a powerful object-oriented design pattern that replaces the older practice of passing callback functions (or hooks, as they're sometimes called, or exits) to foreign code. Unlike classic callback functions, Functors provide an elegant way of maintaining custom state in your callback code, when the exact form or size of that state was not known in advance to the writer of the foreign code that will eventually invoke your callback.
	  Functors in C++ are simple objects that can be invoked just like
	  functions or function pointers can, by virtue of providing the
	  function invocation operator, operator().
	
A simple functor could look like this:
	  struct HelloFunctor
	  {
	  void operator()() { cout << "Hello World" << endl; }
	  };
	...And once an object of this functor type has been created, it can be "invoked" just as if it were a function:
HelloFunctor Hi; Hi();
But the invoking code may also be foreign code knowing nothing about the type of your functor. The foreign code is usually a template, so it automatically becomes "specialized" to your type of functor when the one meets the other:
	  template<typename FUNCTOR> void DoFunctor(const FUNCTOR &Hi)
	  {
	  Hi();
	  }
	
	  The great thing about functors is that they can carry state.  This
	  is most useful when you need to pass a functor object to foreign
	  code like DoFunctor above, but you need
	  certain extra parameters to be passed to your functor that the
	  foreign code isn't going to pass.  The classic C solution to this
	  problem is to let you pass both a function pointer and a
	  pointer-to-void as a method of letting you
	  provide any type of data of your liking to it.  This generally
	  makes programs a little harder to read, and is not very safe or
	  convenient.
	
	  With functors, there is a better way to do the same thing.  Let's
	  say you want to adapt the HelloFunctor class to
	  print its output to a different output stream.  What you'd really
	  like to do is add a parameter to your ()
	  operator to indicate which stream to print to:
	
	  void operator()(ostream &Stream)
	  {
	  Stream << "Hello World" << endl;
	  }
	
	  Unfortunately, DoFunctor doesn't know about
	  this new parameter, let alone what argument to pass!  So instead,
	  let's make this
	  Stream a class member:
	
	  struct HelloFunctor
	  {
	  ostream &Stream;
	  // Set Stream when creating a HelloFunctor
	  explicit HelloFunctor(ostream &S) : Stream(S) { }
	  // Print to output stream selected at construction time
	  void operator()()
	  {
	  Stream << "Hello World" << endl;
	  }
	  };
	
	  We can now provide the necessary information (ie., which stream to
	  print to) to our HelloFunctor before we pass it
	  to DoFunctor:
	
HelloFunctor Hi1(cout), Hi2(cerr); DoFunctor(Hi1); // Print to cout DoFunctor(Hi2); // Print to cerr
	  Naturally a functor's () operator may also return
	  some other type than void, and it may take
	  arguments just like any other function.  This mechanism is used
	  extensively by the STL to sort containers, to find items in sorted
	  containers like set or map, and
	  so on.
	
	  A transactor is a functor derived from an instantiation of
	  libpqxx's transactor class
	  template.  Instead of writing your database transaction inline with
	  the rest of your code, you encapsulate it in your functor's
	  () operator.  When the time comes to execute
	  your transaction, you create an object of your functor type and
	  pass it to the perform method of your
	  connection to the database.
	
	  perform will make a copy of your transactor
	  (which means it needs to be copy-constructible, by the way).  It
	  will also create a transaction object and invoke your transactor's
	  () operator, passing the transaction object to
	  it.  All your transactor needs to do is perform its queries on this
	  object and return, after which perform will
	  commit the transaction.  If your () operator
	  throws an exception instead, perform will
	  discard the copy of your original transactor, and try again with a
	  new copy until it either succeeds or eventually gives up
	  [7].
	  If the connection is lost, the transaction will fail but
	  perform will restore it transparently and
	  simply try again.
	
	  To make all this work, your transactor's ()
	  operator must make no changes to the rest of
	  your program's state.  Any intermediate results, data to be
	  processed, and so on, must stay within your transactor, and be
	  destroyed when the transactor is.  That is the magic trick that
	  allows perform to create copies of your
	  transactor and use them to rerun the transaction as
	  many times as needed, without your program noticing.
	
	  So how does your transactor pass query results back to the outside
	  world once it's done?  For this purpose, you may redefine
	  transactor's OnCommit
	  member function to pass any data back to the rest of your program.
	  This member function will be called only if your transaction
	  succeeded.
	
	  (You may also wish to go the other route, storing data to variables
	  outside the transactor right away, and override the
	  OnAbort and OnDoubt
	  functions to remove the data again if the transaction failed, but
	  this is much more likely to cause subtle bugs.)
	
	  Please refer to the reference manual, the source code, and the test
	  programs that come with libpqxx to learn more
	  about how transactors work.
	
[7] 
	      perform gives up if the transaction fails
	      too many times in succession.  The maximum number of attempts
	      that are made can be passed to perform as
	      an optional second argument.