libpqxx
The C++ client library for PostgreSQL
transactor.hxx
Go to the documentation of this file.
1 /* Transactor framework, a wrapper for safely retryable transactions.
2  *
3  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead.
4  *
5  * Copyright (c) 2000-2026, Jeroen T. Vermeulen.
6  *
7  * See COPYING for copyright license. If you did not receive a file called
8  * COPYING with this source code, please notify the distributor of this
9  * mistake, or contact the author.
10  */
11 #ifndef PQXX_TRANSACTOR_HXX
12 #define PQXX_TRANSACTOR_HXX
13 
14 #if !defined(PQXX_HEADER_PRE)
15 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
16 #endif
17 
18 #include <functional>
19 #include <type_traits>
20 
21 #include "pqxx/connection.hxx"
22 #include "pqxx/transaction.hxx"
23 
24 namespace pqxx
25 {
94 
96 
101 template<typename TRANSACTION_CALLBACK>
102 inline std::invoke_result_t<TRANSACTION_CALLBACK> perform(
103  TRANSACTION_CALLBACK &&callback, int attempts = 3, sl loc = sl::current())
104 {
105  if (attempts <= 0)
106  throw std::invalid_argument{
107  "Zero or negative number of attempts passed to pqxx::perform()."};
108 
109  for (; attempts > 0; --attempts)
110  {
111  try
112  {
113  return std::invoke(callback);
114  }
115  catch (in_doubt_error const &)
116  {
117  // Not sure whether transaction went through or not. The last thing in
118  // the world that we should do now is try again!
119  throw;
120  }
121  catch (statement_completion_unknown const &)
122  {
123  // Not sure whether our last statement succeeded. Don't risk running it
124  // again.
125  throw;
126  }
127  catch (insufficient_resources const &)
128  {
129  // Server is being overloaded. Back off.
130  throw;
131  }
132  catch (too_many_connections const &)
133  {
134  // Server is being overloaded. Back off.
135  throw;
136  }
137  catch (failure const &)
138  {
139  // Some other database-related failure. Retry, unless we've run out of
140  // attempts.
141  if (attempts <= 1)
142  throw;
143  }
144  }
145  throw internal_error{"Reached unreachable transactor state.", loc};
146 }
147 
148 
149 template<typename TRANSACTION_CALLBACK>
150 [[deprecated("No soruce_location needed.")]] inline std::invoke_result_t<
151  TRANSACTION_CALLBACK>
152 perform(TRANSACTION_CALLBACK &&callback, sl loc)
153 {
154  return perform(std::forward(callback), 3, loc);
155 }
156 } // namespace pqxx
158 #endif
Base type for all exceptions specific to libpqxx.
Definition: except.hxx:76
"Help, I don't know whether transaction was committed successfully!"
Definition: except.hxx:451
Resource shortage on the server.
Definition: except.hxx:919
Internal error in libpqxx library.
Definition: except.hxx:558
We can't tell whether our last statement succeeded.
Definition: except.hxx:524
Definition: except.hxx:958
The home of all libpqxx classes, functions, templates, etc.
Definition: array.cxx:26
std::source_location sl
Convenience alias for std::source_location. It's just too long.
Definition: types.hxx:38
std::invoke_result_t< TRANSACTION_CALLBACK > perform(TRANSACTION_CALLBACK &&callback, int attempts=3, sl loc=sl::current())
Simple way to execute a transaction with automatic retry.
Definition: transactor.hxx:102