libpqxx  7.5.1
transactor.hxx
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-2021, 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_H_TRANSACTOR
12 #define PQXX_H_TRANSACTOR
13 
14 #include "pqxx/compiler-public.hxx"
15 #include "pqxx/internal/compiler-internal-pre.hxx"
16 
17 #include <functional>
18 #include <type_traits>
19 
20 #include "pqxx/connection.hxx"
21 #include "pqxx/transaction.hxx"
22 
23 namespace pqxx
24 {
68 
70 
99 template<typename TRANSACTION_CALLBACK>
100 inline auto perform(TRANSACTION_CALLBACK &&callback, int attempts = 3)
101  -> std::invoke_result_t<TRANSACTION_CALLBACK>
102 {
103  if (attempts <= 0)
104  throw std::invalid_argument{
105  "Zero or negative number of attempts passed to pqxx::perform()."};
106 
107  for (; attempts > 0; --attempts)
108  {
109  try
110  {
111  return std::invoke(callback);
112  }
113  catch (in_doubt_error const &)
114  {
115  // Not sure whether transaction went through or not. The last thing in
116  // the world that we should do now is try again!
117  throw;
118  }
119  catch (statement_completion_unknown const &)
120  {
121  // Not sure whether our last statement succeeded. Don't risk running it
122  // again.
123  throw;
124  }
125  catch (broken_connection const &)
126  {
127  // Connection failed. May be worth retrying, if the transactor opens its
128  // own connection.
129  if (attempts <= 1)
130  throw;
131  continue;
132  }
133  catch (transaction_rollback const &)
134  {
135  // Some error that may well be transient, such as serialization failure
136  // or deadlock. Worth retrying.
137  if (attempts <= 1)
138  throw;
139  continue;
140  }
141  }
142  throw pqxx::internal_error{"No outcome reached on perform()."};
143 }
144 } // namespace pqxx
146 
147 #include "pqxx/internal/compiler-internal-post.hxx"
148 #endif
auto perform(TRANSACTION_CALLBACK &&callback, int attempts=3) -> std::invoke_result_t< TRANSACTION_CALLBACK >
Simple way to execute a transaction with automatic retry.
Definition: transactor.hxx:100
The backend saw itself forced to roll back the ongoing transaction.
Definition: except.hxx:113
Exception class for lost or failed backend connection.
Definition: except.hxx:67
We can&#39;t tell whether our last statement succeeded.
Definition: except.hxx:139
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
"Help, I don&#39;t know whether transaction was committed successfully!"
Definition: except.hxx:106
Internal error in libpqxx library.
Definition: except.hxx:157