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