1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-31 18:24:25 +03:00

Fixed after_statement() call to replay if the state was changed

to s_must_replay in rollback() called from after_statement().
This commit is contained in:
Teemu Ollakka
2018-05-31 10:59:15 +03:00
parent 646a2b328e
commit 2f46758064
3 changed files with 17 additions and 10 deletions

View File

@ -541,7 +541,7 @@ namespace trrep
} }
~client_toi_mode() ~client_toi_mode()
{ {
assert(client_.mode == trrep::client_context::m_toi); assert(client_.mode() == trrep::client_context::m_toi);
client_.mode_ = orig_mode_; client_.mode_ = orig_mode_;
} }
private: private:

View File

@ -346,9 +346,10 @@ private:
assert(mode() == trrep::client_context::m_applier); assert(mode() == trrep::client_context::m_applier);
int ret(0); int ret(0);
ret = transaction_context.before_commit(); ret = transaction_context.before_commit();
se_trx_.commit();
ret = ret || transaction_context.ordered_commit(); ret = ret || transaction_context.ordered_commit();
ret = ret || transaction_context.after_commit(); ret = ret || transaction_context.after_commit();
return 0; return ret;
} }
int rollback(trrep::transaction_context& transaction_context) override int rollback(trrep::transaction_context& transaction_context) override
{ {
@ -436,7 +437,7 @@ private:
err = err || after_prepare(); err = err || after_prepare();
} }
err = err || before_commit(); err = err || before_commit();
se_trx_.commit(); if (err == 0) se_trx_.commit();
err = err || ordered_commit(); err = err || ordered_commit();
err = err || after_commit(); err = err || after_commit();
return err; return err;
@ -649,7 +650,7 @@ std::string dbms_simulator::stats() const
<< "\n" << "\n"
<< "Client aborts: " << stats_.aborts << "Client aborts: " << stats_.aborts
<< "\n" << "\n"
<< "Client replays:" << stats_.replays; << "Client replays: " << stats_.replays;
return os.str(); return os.str();
} }

View File

@ -191,12 +191,12 @@ int trrep::transaction_context::before_commit()
trrep::unique_lock<trrep::mutex> lock(client_context_.mutex()); trrep::unique_lock<trrep::mutex> lock(client_context_.mutex());
debug_log_state("before_commit_enter"); debug_log_state("before_commit_enter");
assert(client_context_.mode() != trrep::client_context::m_toi);
assert(state() == s_executing || assert(state() == s_executing ||
state() == s_committing || state() == s_committing ||
state() == s_must_abort || state() == s_must_abort ||
state() == s_replaying); state() == s_replaying);
assert((client_context_.mode() == trrep::client_context::m_replicating && assert(state() != s_committing || certified());
state() == s_executing) || certified());
switch (client_context_.mode()) switch (client_context_.mode())
{ {
@ -433,9 +433,12 @@ int trrep::transaction_context::after_statement()
lock.unlock(); lock.unlock();
ret = client_context_.rollback(*this); ret = client_context_.rollback(*this);
lock.lock(); lock.lock();
break; if (state() != s_must_replay)
case s_aborted: {
break; break;
}
// Continue to replay if rollback() changed the state to s_must_replay
// Fall through
case s_must_replay: case s_must_replay:
state(lock, s_replaying); state(lock, s_replaying);
lock.unlock(); lock.unlock();
@ -443,6 +446,8 @@ int trrep::transaction_context::after_statement()
lock.lock(); lock.lock();
provider_.release(&ws_handle_); provider_.release(&ws_handle_);
break; break;
case s_aborted:
break;
default: default:
assert(0); assert(0);
break; break;
@ -450,7 +455,8 @@ int trrep::transaction_context::after_statement()
assert(state() == s_executing || assert(state() == s_executing ||
state() == s_committed || state() == s_committed ||
state() == s_aborted); state() == s_aborted ||
state() == s_must_replay);
if (state() == s_aborted) if (state() == s_aborted)
{ {