From 2f46758064342d6350be289a3998e6d0add1cf43 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Thu, 31 May 2018 10:59:15 +0300 Subject: [PATCH] Fixed after_statement() call to replay if the state was changed to s_must_replay in rollback() called from after_statement(). --- include/trrep/client_context.hpp | 2 +- src/dbms_simulator.cpp | 7 ++++--- src/transaction_context.cpp | 18 ++++++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/trrep/client_context.hpp b/include/trrep/client_context.hpp index a0afb8e..ad02915 100644 --- a/include/trrep/client_context.hpp +++ b/include/trrep/client_context.hpp @@ -541,7 +541,7 @@ namespace trrep } ~client_toi_mode() { - assert(client_.mode == trrep::client_context::m_toi); + assert(client_.mode() == trrep::client_context::m_toi); client_.mode_ = orig_mode_; } private: diff --git a/src/dbms_simulator.cpp b/src/dbms_simulator.cpp index 3f30484..a0339ef 100644 --- a/src/dbms_simulator.cpp +++ b/src/dbms_simulator.cpp @@ -346,9 +346,10 @@ private: assert(mode() == trrep::client_context::m_applier); int ret(0); ret = transaction_context.before_commit(); + se_trx_.commit(); ret = ret || transaction_context.ordered_commit(); ret = ret || transaction_context.after_commit(); - return 0; + return ret; } int rollback(trrep::transaction_context& transaction_context) override { @@ -436,7 +437,7 @@ private: err = err || after_prepare(); } err = err || before_commit(); - se_trx_.commit(); + if (err == 0) se_trx_.commit(); err = err || ordered_commit(); err = err || after_commit(); return err; @@ -649,7 +650,7 @@ std::string dbms_simulator::stats() const << "\n" << "Client aborts: " << stats_.aborts << "\n" - << "Client replays:" << stats_.replays; + << "Client replays: " << stats_.replays; return os.str(); } diff --git a/src/transaction_context.cpp b/src/transaction_context.cpp index b6a0ded..975cf93 100644 --- a/src/transaction_context.cpp +++ b/src/transaction_context.cpp @@ -191,12 +191,12 @@ int trrep::transaction_context::before_commit() trrep::unique_lock lock(client_context_.mutex()); debug_log_state("before_commit_enter"); + assert(client_context_.mode() != trrep::client_context::m_toi); assert(state() == s_executing || state() == s_committing || state() == s_must_abort || state() == s_replaying); - assert((client_context_.mode() == trrep::client_context::m_replicating && - state() == s_executing) || certified()); + assert(state() != s_committing || certified()); switch (client_context_.mode()) { @@ -433,9 +433,12 @@ int trrep::transaction_context::after_statement() lock.unlock(); ret = client_context_.rollback(*this); lock.lock(); - break; - case s_aborted: - break; + if (state() != s_must_replay) + { + break; + } + // Continue to replay if rollback() changed the state to s_must_replay + // Fall through case s_must_replay: state(lock, s_replaying); lock.unlock(); @@ -443,6 +446,8 @@ int trrep::transaction_context::after_statement() lock.lock(); provider_.release(&ws_handle_); break; + case s_aborted: + break; default: assert(0); break; @@ -450,7 +455,8 @@ int trrep::transaction_context::after_statement() assert(state() == s_executing || state() == s_committed || - state() == s_aborted); + state() == s_aborted || + state() == s_must_replay); if (state() == s_aborted) {