subtransaction.hxx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /** Definition of the pqxx::subtransaction class.
  2. *
  3. * pqxx::subtransaction is a nested transaction, i.e. one within a transaction.
  4. *
  5. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead.
  6. *
  7. * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
  8. *
  9. * See COPYING for copyright license. If you did not receive a file called
  10. * COPYING with this source code, please notify the distributor of this mistake,
  11. * or contact the author.
  12. */
  13. #ifndef PQXX_H_SUBTRANSACTION
  14. #define PQXX_H_SUBTRANSACTION
  15. #include "pqxx/compiler-public.hxx"
  16. #include "pqxx/compiler-internal-pre.hxx"
  17. #include "pqxx/dbtransaction.hxx"
  18. /* Methods tested in eg. self-test program test1 are marked with "//[t01]"
  19. */
  20. namespace pqxx
  21. {
  22. /**
  23. * @ingroup transaction
  24. */
  25. /// "Transaction" nested within another transaction
  26. /** A subtransaction can be executed inside a backend transaction, or inside
  27. * another subtransaction. This can be useful when, for example, statements in
  28. * a transaction may harmlessly fail and you don't want them to abort the entire
  29. * transaction. Here's an example of how a temporary table may be dropped
  30. * before re-creating it, without failing if the table did not exist:
  31. *
  32. * @code
  33. * void do_job(connection_base &C)
  34. * {
  35. * const string temptable = "fleetingtable";
  36. *
  37. * // Since we're dealing with a temporary table here, disallow automatic
  38. * // recovery of the connection in case it breaks.
  39. * C.inhibit_reactivation(true);
  40. *
  41. * work W(C, "do_job");
  42. * do_firstpart(W);
  43. *
  44. * // Attempt to delete our temporary table if it already existed
  45. * try
  46. * {
  47. * subtransaction S(W, "droptemp");
  48. * S.exec0("DROP TABLE " + temptable);
  49. * S.commit();
  50. * }
  51. * catch (const undefined_table &)
  52. * {
  53. * // Table did not exist. Which is what we were hoping to achieve anyway.
  54. * // Carry on without regrets.
  55. * }
  56. *
  57. * // S may have gone into a failed state and been destroyed, but the
  58. * // upper-level transaction W is still fine. We can continue to use it.
  59. * W.exec("CREATE TEMP TABLE " + temptable + "(bar integer, splat varchar)");
  60. *
  61. * do_lastpart(W);
  62. * }
  63. * @endcode
  64. *
  65. * (This is just an example. If you really wanted to do drop a table without an
  66. * error if it doesn't exist, you'd use DROP TABLE IF EXISTS.)
  67. *
  68. * There are no isolation levels inside a transaction. They are not needed
  69. * because all actions within the same backend transaction are always performed
  70. * sequentially anyway.
  71. */
  72. class PQXX_LIBEXPORT subtransaction :
  73. public internal::transactionfocus,
  74. public dbtransaction
  75. {
  76. public:
  77. /// Nest a subtransaction nested in another transaction.
  78. explicit subtransaction( //[t88]
  79. dbtransaction &T, const std::string &Name=std::string{});
  80. /// Nest a subtransaction in another subtransaction.
  81. explicit subtransaction(
  82. subtransaction &T, const std::string &Name=std::string{});
  83. virtual ~subtransaction() noexcept
  84. { End(); }
  85. private:
  86. virtual void do_begin() override; //[t88]
  87. virtual void do_commit() override; //[t88]
  88. virtual void do_abort() override; //[t88]
  89. dbtransaction &m_parent;
  90. };
  91. }
  92. #include "pqxx/compiler-internal-post.hxx"
  93. #endif