diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 4eb8bfd..a6c334d 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -54,6 +54,7 @@ namespace tao::pq friend class connection_pool; friend class table_reader; friend class table_writer; + friend class transaction; friend class transaction_base; friend class internal::top_level_transaction; diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp index ed95661..e938c60 100644 --- a/include/tao/pq/log.hpp +++ b/include/tao/pq/log.hpp @@ -15,6 +15,7 @@ namespace tao::pq { class connection; + class transaction; struct log { @@ -120,7 +121,10 @@ namespace tao::pq struct transaction_t { - // TODO... + // check std::current_exception() for more information + using destructor_rollback_failed_t = std::function< void( transaction& ) >; // noexcept + + destructor_rollback_failed_t destructor_rollback_failed; } transaction; }; diff --git a/include/tao/pq/transaction.hpp b/include/tao/pq/transaction.hpp index 7c7febb..6e6500b 100644 --- a/include/tao/pq/transaction.hpp +++ b/include/tao/pq/transaction.hpp @@ -32,6 +32,8 @@ namespace tao::pq virtual void v_reset() noexcept = 0; + void rollback_in_dtor() noexcept; + public: [[nodiscard]] auto subtransaction() -> std::shared_ptr< transaction >; [[nodiscard]] auto pipeline() -> std::shared_ptr< pq::pipeline >; diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index 580580d..55a7c52 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -137,17 +136,7 @@ namespace tao::pq ~top_level_transaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( const std::exception& ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing exception: " + std::string( e.what() ) ); - } - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing unknown exception" ); - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } diff --git a/src/lib/pq/transaction.cpp b/src/lib/pq/transaction.cpp index ff78442..aad8d0c 100644 --- a/src/lib/pq/transaction.cpp +++ b/src/lib/pq/transaction.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -33,17 +32,7 @@ namespace tao::pq ~top_level_subtransaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( const std::exception& ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing exception: " + std::string( e.what() ) ); - } - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing unknown exception" ); - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } @@ -79,14 +68,7 @@ namespace tao::pq ~nested_subtransaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TODO: How to handle this case properly? - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } @@ -130,8 +112,8 @@ namespace tao::pq void transaction::commit() { - check_current_transaction(); try { + check_current_transaction(); v_commit(); } // LCOV_EXCL_START @@ -145,8 +127,8 @@ namespace tao::pq void transaction::rollback() { - check_current_transaction(); try { + check_current_transaction(); v_rollback(); } // LCOV_EXCL_START @@ -158,4 +140,20 @@ namespace tao::pq v_reset(); } + void transaction::rollback_in_dtor() noexcept + { + try { + check_current_transaction(); + v_rollback(); + } + // LCOV_EXCL_START + catch( ... ) { + if( m_connection->m_log && m_connection->m_log->transaction.destructor_rollback_failed ) { + m_connection->m_log->transaction.destructor_rollback_failed( *this ); + } + } + // LCOV_EXCL_STOP + v_reset(); + } + } // namespace tao::pq