mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-06-16 02:01:44 +03:00
Allow read-only access to transaction context through
client context to enforce use of client context interface for manipulating transaction context state.
This commit is contained in:
@ -189,6 +189,11 @@ namespace trrep
|
|||||||
*/
|
*/
|
||||||
virtual void after_statement();
|
virtual void after_statement();
|
||||||
|
|
||||||
|
int start_transaction()
|
||||||
|
{
|
||||||
|
assert(state_ == s_exec);
|
||||||
|
return transaction_.start_transaction();
|
||||||
|
}
|
||||||
int start_transaction(const trrep::transaction_id& id)
|
int start_transaction(const trrep::transaction_id& id)
|
||||||
{
|
{
|
||||||
assert(state_ == s_exec);
|
assert(state_ == s_exec);
|
||||||
@ -253,6 +258,12 @@ namespace trrep
|
|||||||
assert(state_ == s_exec);
|
assert(state_ == s_exec);
|
||||||
return transaction_.after_rollback();
|
return transaction_.after_rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bf_abort(trrep::unique_lock<trrep::mutex>& lock,
|
||||||
|
wsrep_seqno_t bf_seqno)
|
||||||
|
{
|
||||||
|
return transaction_.bf_abort(lock, bf_seqno);
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
* Get reference to the client mutex.
|
* Get reference to the client mutex.
|
||||||
*
|
*
|
||||||
@ -294,7 +305,7 @@ namespace trrep
|
|||||||
*/
|
*/
|
||||||
enum mode mode() const { return mode_; }
|
enum mode mode() const { return mode_; }
|
||||||
|
|
||||||
trrep::transaction_context& transaction()
|
const trrep::transaction_context& transaction() const
|
||||||
{
|
{
|
||||||
return transaction_;
|
return transaction_;
|
||||||
}
|
}
|
||||||
@ -343,7 +354,6 @@ namespace trrep
|
|||||||
* Friend declarations
|
* Friend declarations
|
||||||
*/
|
*/
|
||||||
friend int server_context::on_apply(client_context&,
|
friend int server_context::on_apply(client_context&,
|
||||||
trrep::transaction_context&,
|
|
||||||
const trrep::data&);
|
const trrep::data&);
|
||||||
friend class client_context_switch;
|
friend class client_context_switch;
|
||||||
friend class client_applier_mode;
|
friend class client_applier_mode;
|
||||||
@ -387,8 +397,7 @@ namespace trrep
|
|||||||
*
|
*
|
||||||
* \return Zero on success, non-zero on applying failure.
|
* \return Zero on success, non-zero on applying failure.
|
||||||
*/
|
*/
|
||||||
virtual int apply(trrep::transaction_context& transaction,
|
virtual int apply(const trrep::data& data) = 0;
|
||||||
const trrep::data& data) = 0;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method which will be called
|
* Virtual method which will be called
|
||||||
@ -397,7 +406,7 @@ namespace trrep
|
|||||||
*
|
*
|
||||||
* \return Zero on success, non-zero on failure.
|
* \return Zero on success, non-zero on failure.
|
||||||
*/
|
*/
|
||||||
virtual int commit(trrep::transaction_context&) = 0;
|
virtual int commit() = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Rollback the transaction.
|
* Rollback the transaction.
|
||||||
@ -406,7 +415,7 @@ namespace trrep
|
|||||||
*
|
*
|
||||||
* \return Zero on success, no-zero on failure.
|
* \return Zero on success, no-zero on failure.
|
||||||
*/
|
*/
|
||||||
virtual int rollback(trrep::transaction_context&) = 0;
|
virtual int rollback() = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Notify a implementation that the client is about
|
* Notify a implementation that the client is about
|
||||||
@ -482,7 +491,9 @@ namespace trrep
|
|||||||
client_id id_;
|
client_id id_;
|
||||||
enum mode mode_;
|
enum mode mode_;
|
||||||
enum state state_;
|
enum state state_;
|
||||||
|
protected:
|
||||||
trrep::transaction_context transaction_;
|
trrep::transaction_context transaction_;
|
||||||
|
private:
|
||||||
/*!
|
/*!
|
||||||
* \todo This boolean should be converted to better read isolation
|
* \todo This boolean should be converted to better read isolation
|
||||||
* semantics.
|
* semantics.
|
||||||
|
@ -333,7 +333,6 @@ namespace trrep
|
|||||||
* \return Zero on success, non-zero on failure.
|
* \return Zero on success, non-zero on failure.
|
||||||
*/
|
*/
|
||||||
int on_apply(trrep::client_context& client_context,
|
int on_apply(trrep::client_context& client_context,
|
||||||
trrep::transaction_context& transaction_context,
|
|
||||||
const trrep::data& data);
|
const trrep::data& data);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -73,7 +73,7 @@ namespace trrep
|
|||||||
|
|
||||||
// Return true if the certification of the last
|
// Return true if the certification of the last
|
||||||
// fragment succeeded
|
// fragment succeeded
|
||||||
bool certified() { return certified_; }
|
bool certified() const { return certified_; }
|
||||||
|
|
||||||
wsrep_seqno_t seqno() const
|
wsrep_seqno_t seqno() const
|
||||||
{
|
{
|
||||||
@ -130,7 +130,7 @@ namespace trrep
|
|||||||
int after_statement();
|
int after_statement();
|
||||||
|
|
||||||
bool bf_abort(trrep::unique_lock<trrep::mutex>& lock,
|
bool bf_abort(trrep::unique_lock<trrep::mutex>& lock,
|
||||||
const transaction_context& txc);
|
wsrep_seqno_t bf_seqno);
|
||||||
|
|
||||||
uint32_t flags() const
|
uint32_t flags() const
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ void trrep::client_context::after_command()
|
|||||||
{
|
{
|
||||||
override_error(trrep::e_deadlock_error);
|
override_error(trrep::e_deadlock_error);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
rollback(transaction_);
|
rollback();
|
||||||
transaction_.after_statement();
|
transaction_.after_statement();
|
||||||
lock.lock();
|
lock.lock();
|
||||||
assert(transaction_.state() == trrep::transaction_context::s_aborted);
|
assert(transaction_.state() == trrep::transaction_context::s_aborted);
|
||||||
@ -77,7 +77,7 @@ int trrep::client_context::before_statement()
|
|||||||
{
|
{
|
||||||
override_error(trrep::e_deadlock_error);
|
override_error(trrep::e_deadlock_error);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
rollback(transaction_);
|
rollback();
|
||||||
lock.lock();
|
lock.lock();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@ BOOST_AUTO_TEST_CASE(client_context_test_error_codes)
|
|||||||
trrep::client_id(1),
|
trrep::client_id(1),
|
||||||
trrep::client_context::m_applier,
|
trrep::client_context::m_applier,
|
||||||
false);
|
false);
|
||||||
|
const trrep::transaction_context& txc(cc.transaction());
|
||||||
|
cc.before_command();
|
||||||
|
cc.before_statement();
|
||||||
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
BOOST_REQUIRE(txc.active() == false);
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
cc.start_transaction(1);
|
||||||
tc.start_transaction(1);
|
trrep_mock::bf_abort_unordered(cc);
|
||||||
trrep_mock::bf_abort_unordered(cc, tc);
|
|
||||||
|
|
||||||
BOOST_REQUIRE(cc.before_command());
|
|
||||||
BOOST_REQUIRE(cc.before_statement());
|
|
||||||
cc.after_statement();
|
cc.after_statement();
|
||||||
cc.after_command();
|
cc.after_command();
|
||||||
}
|
}
|
||||||
|
@ -70,41 +70,41 @@ public:
|
|||||||
public:
|
public:
|
||||||
transaction(dbms_storage_engine& se)
|
transaction(dbms_storage_engine& se)
|
||||||
: se_(se)
|
: se_(se)
|
||||||
, txc_()
|
, cc_()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool active() const { return txc_ != nullptr; }
|
bool active() const { return cc_ != nullptr; }
|
||||||
|
|
||||||
void start(trrep::transaction_context* txc)
|
void start(trrep::client_context* cc)
|
||||||
{
|
{
|
||||||
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
||||||
if (se_.transactions_.insert(txc).second == false)
|
if (se_.transactions_.insert(cc).second == false)
|
||||||
{
|
{
|
||||||
::abort();
|
::abort();
|
||||||
}
|
}
|
||||||
txc_ = txc;
|
cc_ = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void commit()
|
void commit()
|
||||||
{
|
{
|
||||||
if (txc_)
|
if (cc_)
|
||||||
{
|
{
|
||||||
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
||||||
se_.transactions_.erase(txc_);
|
se_.transactions_.erase(cc_);
|
||||||
}
|
}
|
||||||
txc_ = nullptr;
|
cc_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void abort()
|
void abort()
|
||||||
{
|
{
|
||||||
if (txc_)
|
if (cc_)
|
||||||
{
|
{
|
||||||
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
trrep::unique_lock<trrep::mutex> lock(se_.mutex_);
|
||||||
se_.transactions_.erase(txc_);
|
se_.transactions_.erase(cc_);
|
||||||
}
|
}
|
||||||
txc_ = nullptr;
|
cc_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
~transaction()
|
~transaction()
|
||||||
@ -117,7 +117,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
dbms_storage_engine& se_;
|
dbms_storage_engine& se_;
|
||||||
trrep::transaction_context* txc_;
|
trrep::client_context* cc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void bf_abort_some(const trrep::transaction_context& txc)
|
void bf_abort_some(const trrep::transaction_context& txc)
|
||||||
@ -131,7 +131,7 @@ public:
|
|||||||
trrep::unique_lock<trrep::mutex> victim_txc_lock(
|
trrep::unique_lock<trrep::mutex> victim_txc_lock(
|
||||||
victim_txc->mutex());
|
victim_txc->mutex());
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
if (victim_txc->bf_abort(victim_txc_lock, txc))
|
if (victim_txc->bf_abort(victim_txc_lock, txc.seqno()))
|
||||||
{
|
{
|
||||||
trrep::log() << "BF aborted " << victim_txc->id().get();
|
trrep::log() << "BF aborted " << victim_txc->id().get();
|
||||||
++bf_aborts_;
|
++bf_aborts_;
|
||||||
@ -146,7 +146,7 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
trrep::default_mutex mutex_;
|
trrep::default_mutex mutex_;
|
||||||
std::unordered_set<trrep::transaction_context*> transactions_;
|
std::unordered_set<trrep::client_context*> transactions_;
|
||||||
size_t alg_freq_;
|
size_t alg_freq_;
|
||||||
std::atomic<long long> bf_aborts_;
|
std::atomic<long long> bf_aborts_;
|
||||||
};
|
};
|
||||||
@ -337,28 +337,28 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool do_2pc() const override { return false; }
|
bool do_2pc() const override { return false; }
|
||||||
int apply(trrep::transaction_context& txc, const trrep::data& data) override
|
int apply(const trrep::data& data) override
|
||||||
{
|
{
|
||||||
return server_.apply_to_storage_engine(txc, data);
|
return server_.apply_to_storage_engine(transaction(), data);
|
||||||
}
|
}
|
||||||
int commit(trrep::transaction_context& transaction_context) override
|
int commit() override
|
||||||
{
|
{
|
||||||
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 = before_commit();
|
||||||
se_trx_.commit();
|
se_trx_.commit();
|
||||||
ret = ret || transaction_context.ordered_commit();
|
ret = ret || ordered_commit();
|
||||||
ret = ret || transaction_context.after_commit();
|
ret = ret || after_commit();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int rollback(trrep::transaction_context& transaction_context) override
|
int rollback() override
|
||||||
{
|
{
|
||||||
trrep::log() << "rollback: " << transaction_context.id().get()
|
trrep::log() << "rollback: " << transaction().id().get()
|
||||||
<< "state: "
|
<< "state: "
|
||||||
<< trrep::to_string(transaction_context.state());
|
<< trrep::to_string(transaction().state());
|
||||||
transaction_context.before_rollback();
|
before_rollback();
|
||||||
se_trx_.abort();
|
se_trx_.abort();
|
||||||
transaction_context.after_rollback();
|
after_rollback();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ private:
|
|||||||
{
|
{
|
||||||
err = start_transaction(server_.next_transaction_id());
|
err = start_transaction(server_.next_transaction_id());
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
se_trx_.start(&transaction());
|
se_trx_.start(this);
|
||||||
return err;
|
return err;
|
||||||
});
|
});
|
||||||
err = err || current_error();
|
err = err || current_error();
|
||||||
|
@ -7,48 +7,45 @@
|
|||||||
|
|
||||||
|
|
||||||
int trrep::mock_client_context::apply(
|
int trrep::mock_client_context::apply(
|
||||||
trrep::transaction_context& transaction_context __attribute__((unused)),
|
|
||||||
const trrep::data& data __attribute__((unused)))
|
const trrep::data& data __attribute__((unused)))
|
||||||
|
|
||||||
{
|
{
|
||||||
assert(transaction_context.state() == trrep::transaction_context::s_executing);
|
assert(transaction_.state() == trrep::transaction_context::s_executing);
|
||||||
return (fail_next_applying_ ? 1 : 0);
|
return (fail_next_applying_ ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trrep::mock_client_context::commit(
|
int trrep::mock_client_context::commit()
|
||||||
trrep::transaction_context& transaction_context)
|
|
||||||
{
|
{
|
||||||
int ret(0);
|
int ret(0);
|
||||||
if (do_2pc())
|
if (do_2pc())
|
||||||
{
|
{
|
||||||
if (transaction_context.before_prepare())
|
if (transaction_.before_prepare())
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else if (transaction_context.after_prepare())
|
else if (transaction_.after_prepare())
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == 0 &&
|
if (ret == 0 &&
|
||||||
(transaction_context.before_commit() ||
|
(transaction_.before_commit() ||
|
||||||
transaction_context.ordered_commit() ||
|
transaction_.ordered_commit() ||
|
||||||
transaction_context.after_commit()))
|
transaction_.after_commit()))
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trrep::mock_client_context::rollback(
|
int trrep::mock_client_context::rollback()
|
||||||
trrep::transaction_context& transaction_context)
|
|
||||||
{
|
{
|
||||||
int ret(0);
|
int ret(0);
|
||||||
if (transaction_context.before_rollback())
|
if (transaction_.before_rollback())
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else if (transaction_context.after_rollback())
|
else if (transaction_.after_rollback())
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ namespace trrep
|
|||||||
{
|
{
|
||||||
if (transaction().active())
|
if (transaction().active())
|
||||||
{
|
{
|
||||||
(void)rollback(transaction());
|
(void)rollback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int apply(trrep::transaction_context&, const trrep::data&);
|
int apply(const trrep::data&);
|
||||||
int commit(trrep::transaction_context&);
|
int commit();
|
||||||
int rollback(trrep::transaction_context&);
|
int rollback();
|
||||||
bool do_2pc() const { return do_2pc_; }
|
bool do_2pc() const { return do_2pc_; }
|
||||||
void will_replay(trrep::transaction_context&) TRREP_OVERRIDE { }
|
void will_replay(trrep::transaction_context&) TRREP_OVERRIDE { }
|
||||||
int replay(trrep::transaction_context& tc) TRREP_OVERRIDE
|
int replay(trrep::transaction_context& tc) TRREP_OVERRIDE
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
|
|
||||||
// Simple BF abort method to BF abort unordered transasctions
|
// Simple BF abort method to BF abort unordered transasctions
|
||||||
void trrep_mock::bf_abort_unordered(trrep::client_context& cc,
|
void trrep_mock::bf_abort_unordered(trrep::client_context& cc)
|
||||||
trrep::transaction_context& tc)
|
|
||||||
{
|
{
|
||||||
trrep::unique_lock<trrep::mutex> lock(cc.mutex());
|
trrep::unique_lock<trrep::mutex> lock(cc.mutex());
|
||||||
tc.state(lock, trrep::transaction_context::s_must_abort);
|
assert(cc.transaction().seqno() <= 0);
|
||||||
|
cc.bf_abort(lock, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BF abort method to abort transactions via provider
|
// BF abort method to abort transactions via provider
|
||||||
@ -25,7 +25,7 @@ void trrep_mock::bf_abort_provider(trrep::mock_server_context& sc,
|
|||||||
(void)victim_seqno;
|
(void)victim_seqno;
|
||||||
}
|
}
|
||||||
|
|
||||||
trrep::transaction_context& trrep_mock::start_applying_transaction(
|
void trrep_mock::start_applying_transaction(
|
||||||
trrep::client_context& cc,
|
trrep::client_context& cc,
|
||||||
const trrep::transaction_id& id,
|
const trrep::transaction_id& id,
|
||||||
wsrep_seqno_t seqno,
|
wsrep_seqno_t seqno,
|
||||||
@ -42,5 +42,4 @@ trrep::transaction_context& trrep_mock::start_applying_transaction(
|
|||||||
{
|
{
|
||||||
throw trrep::runtime_error("failed to start applying transaction");
|
throw trrep::runtime_error("failed to start applying transaction");
|
||||||
}
|
}
|
||||||
return cc.transaction();
|
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,14 @@ namespace trrep_mock
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Simple BF abort method to BF abort unordered transasctions
|
// Simple BF abort method to BF abort unordered transasctions
|
||||||
void bf_abort_unordered(trrep::client_context& cc,
|
void bf_abort_unordered(trrep::client_context& cc);
|
||||||
trrep::transaction_context& tc);
|
|
||||||
|
|
||||||
// BF abort method to abort transactions via provider
|
// BF abort method to abort transactions via provider
|
||||||
void bf_abort_provider(trrep::mock_server_context& sc,
|
void bf_abort_provider(trrep::mock_server_context& sc,
|
||||||
const trrep::transaction_context& tc,
|
const trrep::transaction_context& tc,
|
||||||
wsrep_seqno_t bf_seqno);
|
wsrep_seqno_t bf_seqno);
|
||||||
|
|
||||||
trrep::transaction_context& start_applying_transaction(
|
void start_applying_transaction(
|
||||||
trrep::client_context& cc,
|
trrep::client_context& cc,
|
||||||
const trrep::transaction_id& id,
|
const trrep::transaction_id& id,
|
||||||
wsrep_seqno_t seqno,
|
wsrep_seqno_t seqno,
|
||||||
|
@ -122,7 +122,7 @@ namespace
|
|||||||
}
|
}
|
||||||
if (ret == WSREP_CB_SUCCESS &&
|
if (ret == WSREP_CB_SUCCESS &&
|
||||||
client_context->server_context().on_apply(
|
client_context->server_context().on_apply(
|
||||||
*client_context, client_context->transaction(), data))
|
*client_context, data))
|
||||||
{
|
{
|
||||||
ret = WSREP_CB_FAILURE;
|
ret = WSREP_CB_FAILURE;
|
||||||
}
|
}
|
||||||
@ -296,29 +296,35 @@ void trrep::server_context::on_sync()
|
|||||||
|
|
||||||
int trrep::server_context::on_apply(
|
int trrep::server_context::on_apply(
|
||||||
trrep::client_context& client_context,
|
trrep::client_context& client_context,
|
||||||
trrep::transaction_context& transaction_context,
|
|
||||||
const trrep::data& data)
|
const trrep::data& data)
|
||||||
{
|
{
|
||||||
int ret(0);
|
int ret(0);
|
||||||
if (starts_transaction(transaction_context.flags()) &&
|
const trrep::transaction_context& txc(client_context.transaction());
|
||||||
commits_transaction(transaction_context.flags()))
|
if (starts_transaction(txc.flags()) &&
|
||||||
|
commits_transaction(txc.flags()))
|
||||||
{
|
{
|
||||||
if (transaction_context.state() != trrep::transaction_context::s_replaying)
|
if (txc.state() != trrep::transaction_context::s_replaying)
|
||||||
{
|
{
|
||||||
assert(transaction_context.active() == false);
|
client_context.before_command();
|
||||||
transaction_context.start_transaction();
|
client_context.before_statement();
|
||||||
|
assert(txc.active() == false);
|
||||||
|
client_context.start_transaction();
|
||||||
}
|
}
|
||||||
if (client_context.apply(transaction_context, data))
|
if (client_context.apply(data))
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else if (client_context.commit(transaction_context))
|
else if (client_context.commit())
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
if (txc.state() != trrep::transaction_context::s_replaying)
|
||||||
|
{
|
||||||
|
client_context.after_statement();
|
||||||
|
client_context.after_command();
|
||||||
|
}
|
||||||
assert(ret ||
|
assert(ret ||
|
||||||
transaction_context.state() ==
|
txc.state() == trrep::transaction_context::s_committed);
|
||||||
trrep::transaction_context::s_committed);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -328,11 +334,11 @@ int trrep::server_context::on_apply(
|
|||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
client_context.rollback(transaction_context);
|
client_context.rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_context.after_statement();
|
client_context.after_statement();
|
||||||
assert(transaction_context.active() == false);
|
assert(txc.active() == false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ BOOST_AUTO_TEST_CASE(server_context_applying_1pc)
|
|||||||
trrep::client_id(1),
|
trrep::client_id(1),
|
||||||
trrep::client_context::m_applier,
|
trrep::client_context::m_applier,
|
||||||
false);
|
false);
|
||||||
trrep::transaction_context& tc(
|
|
||||||
trrep_mock::start_applying_transaction(
|
trrep_mock::start_applying_transaction(
|
||||||
cc, 1, 1,
|
cc, 1, 1,
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
char buf[1] = { 1 };
|
char buf[1] = { 1 };
|
||||||
BOOST_REQUIRE(sc.on_apply(cc, tc, trrep::data(buf, 1)) == 0);
|
BOOST_REQUIRE(sc.on_apply(cc, trrep::data(buf, 1)) == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
const trrep::transaction_context& txc(cc.transaction());
|
||||||
|
BOOST_REQUIRE(txc.state() == trrep::transaction_context::s_committed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test on_apply() method for 2pc
|
// Test on_apply() method for 2pc
|
||||||
@ -34,13 +34,13 @@ BOOST_AUTO_TEST_CASE(server_context_applying_2pc)
|
|||||||
trrep::client_id(1),
|
trrep::client_id(1),
|
||||||
trrep::client_context::m_applier,
|
trrep::client_context::m_applier,
|
||||||
true);
|
true);
|
||||||
trrep::transaction_context& tc(
|
|
||||||
trrep_mock::start_applying_transaction(
|
trrep_mock::start_applying_transaction(
|
||||||
cc, 1, 1,
|
cc, 1, 1,
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
char buf[1] = { 1 };
|
char buf[1] = { 1 };
|
||||||
BOOST_REQUIRE(sc.on_apply(cc, tc, trrep::data(buf, 1)) == 0);
|
BOOST_REQUIRE(sc.on_apply(cc, trrep::data(buf, 1)) == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
const trrep::transaction_context& txc(cc.transaction());
|
||||||
|
BOOST_REQUIRE(txc.state() == trrep::transaction_context::s_committed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test on_apply() method for 1pc transaction which
|
// Test on_apply() method for 1pc transaction which
|
||||||
@ -54,14 +54,14 @@ BOOST_AUTO_TEST_CASE(server_context_applying_1pc_rollback)
|
|||||||
trrep::client_context::m_applier,
|
trrep::client_context::m_applier,
|
||||||
false);
|
false);
|
||||||
cc.fail_next_applying(true);
|
cc.fail_next_applying(true);
|
||||||
trrep::transaction_context& tc(
|
|
||||||
trrep_mock::start_applying_transaction(
|
trrep_mock::start_applying_transaction(
|
||||||
cc, 1, 1,
|
cc, 1, 1,
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
char buf[1] = { 1 };
|
char buf[1] = { 1 };
|
||||||
|
|
||||||
BOOST_REQUIRE(sc.on_apply(cc, tc, trrep::data(buf, 1)) == 1);
|
BOOST_REQUIRE(sc.on_apply(cc, trrep::data(buf, 1)) == 1);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
const trrep::transaction_context& txc(cc.transaction());
|
||||||
|
BOOST_REQUIRE(txc.state() == trrep::transaction_context::s_aborted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test on_apply() method for 2pc transaction which
|
// Test on_apply() method for 2pc transaction which
|
||||||
@ -75,11 +75,11 @@ BOOST_AUTO_TEST_CASE(server_context_applying_2pc_rollback)
|
|||||||
trrep::client_context::m_applier,
|
trrep::client_context::m_applier,
|
||||||
true);
|
true);
|
||||||
cc.fail_next_applying(true);
|
cc.fail_next_applying(true);
|
||||||
trrep::transaction_context& tc(
|
|
||||||
trrep_mock::start_applying_transaction(
|
trrep_mock::start_applying_transaction(
|
||||||
cc, 1, 1,
|
cc, 1, 1,
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
char buf[1] = { 1 };
|
char buf[1] = { 1 };
|
||||||
BOOST_REQUIRE(sc.on_apply(cc, tc, trrep::data(buf, 1)) == 1);
|
BOOST_REQUIRE(sc.on_apply(cc, trrep::data(buf, 1)) == 1);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
const trrep::transaction_context& txc(cc.transaction());
|
||||||
|
BOOST_REQUIRE(txc.state() == trrep::transaction_context::s_aborted);
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ int trrep::transaction_context::after_statement()
|
|||||||
case s_cert_failed:
|
case s_cert_failed:
|
||||||
client_context_.override_error(trrep::e_deadlock_error);
|
client_context_.override_error(trrep::e_deadlock_error);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
ret = client_context_.rollback(*this);
|
ret = client_context_.rollback();
|
||||||
lock.lock();
|
lock.lock();
|
||||||
if (state() != s_must_replay)
|
if (state() != s_must_replay)
|
||||||
{
|
{
|
||||||
@ -480,7 +480,7 @@ int trrep::transaction_context::after_statement()
|
|||||||
|
|
||||||
bool trrep::transaction_context::bf_abort(
|
bool trrep::transaction_context::bf_abort(
|
||||||
trrep::unique_lock<trrep::mutex>& lock TRREP_UNUSED,
|
trrep::unique_lock<trrep::mutex>& lock TRREP_UNUSED,
|
||||||
const trrep::transaction_context& txc)
|
wsrep_seqno_t bf_seqno)
|
||||||
{
|
{
|
||||||
bool ret(false);
|
bool ret(false);
|
||||||
assert(lock.owns_lock());
|
assert(lock.owns_lock());
|
||||||
@ -490,10 +490,10 @@ bool trrep::transaction_context::bf_abort(
|
|||||||
{
|
{
|
||||||
trrep::log() << "Transaction not active, skipping bf abort";
|
trrep::log() << "Transaction not active, skipping bf abort";
|
||||||
}
|
}
|
||||||
else if (ordered() && seqno() < txc.seqno())
|
else if (ordered() && seqno() < bf_seqno)
|
||||||
{
|
{
|
||||||
trrep::log() << "Not allowed to BF abort transaction ordered before "
|
trrep::log() << "Not allowed to BF abort transaction ordered before "
|
||||||
<< "aborter: " << seqno() << " < " << txc.seqno();
|
<< "aborter: " << seqno() << " < " << bf_seqno;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -506,11 +506,11 @@ bool trrep::transaction_context::bf_abort(
|
|||||||
{
|
{
|
||||||
wsrep_seqno_t victim_seqno(WSREP_SEQNO_UNDEFINED);
|
wsrep_seqno_t victim_seqno(WSREP_SEQNO_UNDEFINED);
|
||||||
wsrep_status_t status(client_context_.provider().bf_abort(
|
wsrep_status_t status(client_context_.provider().bf_abort(
|
||||||
txc.seqno(), id_.get(), &victim_seqno));
|
bf_seqno, id_.get(), &victim_seqno));
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case WSREP_OK:
|
case WSREP_OK:
|
||||||
trrep::log() << "Seqno " << txc.seqno()
|
trrep::log() << "Seqno " << bf_seqno
|
||||||
<< " succesfully BF aborted " << id_.get()
|
<< " succesfully BF aborted " << id_.get()
|
||||||
<< " victim_seqno " << victim_seqno;
|
<< " victim_seqno " << victim_seqno;
|
||||||
bf_abort_state_ = state();
|
bf_abort_state_ = state();
|
||||||
@ -518,7 +518,7 @@ bool trrep::transaction_context::bf_abort(
|
|||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
trrep::log() << "Seqno " << txc.seqno()
|
trrep::log() << "Seqno " << bf_seqno
|
||||||
<< " failed to BF abort " << id_.get()
|
<< " failed to BF abort " << id_.get()
|
||||||
<< " with status " << status
|
<< " with status " << status
|
||||||
<< " victim_seqno " << victim_seqno;
|
<< " victim_seqno " << victim_seqno;
|
||||||
@ -588,6 +588,7 @@ void trrep::transaction_context::state(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
int trrep::transaction_context::certify_fragment(
|
int trrep::transaction_context::certify_fragment(
|
||||||
trrep::unique_lock<trrep::mutex>& lock)
|
trrep::unique_lock<trrep::mutex>& lock)
|
||||||
{
|
{
|
||||||
@ -658,6 +659,7 @@ int trrep::transaction_context::certify_fragment(
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int trrep::transaction_context::certify_commit(
|
int trrep::transaction_context::certify_commit(
|
||||||
trrep::unique_lock<trrep::mutex>& lock)
|
trrep::unique_lock<trrep::mutex>& lock)
|
||||||
|
@ -12,41 +12,82 @@
|
|||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
//
|
namespace
|
||||||
// Test a succesful 1PC transaction lifecycle
|
|
||||||
//
|
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc)
|
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
struct replicating_client_fixture
|
||||||
trrep::server_context::rm_sync);
|
{
|
||||||
trrep::mock_client_context cc(sc,trrep::client_id(1),
|
replicating_client_fixture()
|
||||||
trrep::client_context::m_replicating);
|
: sc("s1", "s1", trrep::server_context::rm_async)
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
, cc(sc, trrep::client_id(1),
|
||||||
|
trrep::client_context::m_replicating)
|
||||||
|
, tc(cc.transaction())
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE(cc.before_command() == 0);
|
||||||
|
BOOST_REQUIRE(cc.before_statement() == 0);
|
||||||
// Verify initial state
|
// Verify initial state
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
}
|
||||||
|
trrep::mock_server_context sc;
|
||||||
|
trrep::mock_client_context cc;
|
||||||
|
const trrep::transaction_context& tc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct applying_client_fixture
|
||||||
|
{
|
||||||
|
applying_client_fixture()
|
||||||
|
: sc("s1", "s1",
|
||||||
|
trrep::server_context::rm_async)
|
||||||
|
, cc(sc,
|
||||||
|
trrep::client_id(1),
|
||||||
|
trrep::client_context::m_applier)
|
||||||
|
, tc(cc.transaction())
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE(cc.before_command() == 0);
|
||||||
|
BOOST_REQUIRE(cc.before_statement() == 0);
|
||||||
|
trrep_mock::start_applying_transaction(
|
||||||
|
cc, 1, 1,
|
||||||
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
|
BOOST_REQUIRE(cc.start_transaction() == 0);
|
||||||
|
BOOST_REQUIRE(tc.active() == true);
|
||||||
|
BOOST_REQUIRE(tc.certified() == true);
|
||||||
|
BOOST_REQUIRE(tc.ordered() == true);
|
||||||
|
}
|
||||||
|
trrep::mock_server_context sc;
|
||||||
|
trrep::mock_client_context cc;
|
||||||
|
const trrep::transaction_context& tc;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test a succesful 1PC transaction lifecycle
|
||||||
|
//
|
||||||
|
BOOST_FIXTURE_TEST_CASE(transaction_context_1pc, replicating_client_fixture)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_commit() == 0);
|
BOOST_REQUIRE(cc.before_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
|
|
||||||
// Run ordered commit
|
// Run ordered commit
|
||||||
BOOST_REQUIRE(tc.ordered_commit() == 0);
|
BOOST_REQUIRE(cc.ordered_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
||||||
|
|
||||||
// Run after commit
|
// Run after commit
|
||||||
BOOST_REQUIRE(tc.after_commit() == 0);
|
BOOST_REQUIRE(cc.after_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -56,45 +97,36 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc)
|
|||||||
//
|
//
|
||||||
// Test a succesful 2PC transaction lifecycle
|
// Test a succesful 2PC transaction lifecycle
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_2pc)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_2pc, replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
// Run before prepare
|
// Run before prepare
|
||||||
BOOST_REQUIRE(tc.before_prepare() == 0);
|
BOOST_REQUIRE(cc.before_prepare() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
||||||
|
|
||||||
// Run after prepare
|
// Run after prepare
|
||||||
BOOST_REQUIRE(tc.after_prepare() == 0);
|
BOOST_REQUIRE(cc.after_prepare() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_commit() == 0);
|
BOOST_REQUIRE(cc.before_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
|
|
||||||
// Run ordered commit
|
// Run ordered commit
|
||||||
BOOST_REQUIRE(tc.ordered_commit() == 0);
|
BOOST_REQUIRE(cc.ordered_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
||||||
|
|
||||||
// Run after commit
|
// Run after commit
|
||||||
BOOST_REQUIRE(tc.after_commit() == 0);
|
BOOST_REQUIRE(cc.after_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -104,34 +136,24 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc)
|
|||||||
//
|
//
|
||||||
// Test a voluntary rollback
|
// Test a voluntary rollback
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_rollback)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_rollback, replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc,trrep::client_id(1),
|
|
||||||
trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
|
|
||||||
// Run after commit
|
// Run after commit
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -141,39 +163,31 @@ BOOST_AUTO_TEST_CASE(transaction_context_rollback)
|
|||||||
//
|
//
|
||||||
// Test a 1PC transaction which gets BF aborted before before_commit
|
// Test a 1PC transaction which gets BF aborted before before_commit
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_before_before_commit)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_1pc_bf_before_before_commit,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
trrep_mock::bf_abort_unordered(cc, tc);
|
trrep_mock::bf_abort_unordered(cc);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_commit());
|
BOOST_REQUIRE(cc.before_commit());
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
|
|
||||||
// Rollback sequence
|
// Rollback sequence
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -183,39 +197,31 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_before_before_commit)
|
|||||||
//
|
//
|
||||||
// Test a 2PC transaction which gets BF aborted before before_prepare
|
// Test a 2PC transaction which gets BF aborted before before_prepare
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_2pc_bf_before_before_prepare)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_2pc_bf_before_before_prepare,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
trrep_mock::bf_abort_unordered(cc, tc);
|
trrep_mock::bf_abort_unordered(cc);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_prepare());
|
BOOST_REQUIRE(cc.before_prepare());
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
|
|
||||||
// Rollback sequence
|
// Rollback sequence
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -225,43 +231,35 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc_bf_before_before_prepare)
|
|||||||
//
|
//
|
||||||
// Test a 2PC transaction which gets BF aborted before before_prepare
|
// Test a 2PC transaction which gets BF aborted before before_prepare
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_2pc_bf_before_after_prepare)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_2pc_bf_before_after_prepare,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
// Run before prepare
|
// Run before prepare
|
||||||
BOOST_REQUIRE(tc.before_prepare() == 0);
|
BOOST_REQUIRE(cc.before_prepare() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
||||||
|
|
||||||
trrep_mock::bf_abort_unordered(cc, tc);
|
trrep_mock::bf_abort_unordered(cc);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.after_prepare());
|
BOOST_REQUIRE(cc.after_prepare());
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_abort);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
|
|
||||||
// Rollback sequence
|
// Rollback sequence
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -272,19 +270,12 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc_bf_before_after_prepare)
|
|||||||
// Test a 1PC transaction which gets BF aborted during before_commit via
|
// Test a 1PC transaction which gets BF aborted during before_commit via
|
||||||
// provider before the write set was ordered and certified.
|
// provider before the write set was ordered and certified.
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_uncertified)
|
BOOST_FIXTURE_TEST_CASE(
|
||||||
|
transaction_context_1pc_bf_during_before_commit_uncertified,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
@ -292,19 +283,19 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_uncertified
|
|||||||
trrep_mock::bf_abort_provider(sc, tc, WSREP_SEQNO_UNDEFINED);
|
trrep_mock::bf_abort_provider(sc, tc, WSREP_SEQNO_UNDEFINED);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_commit());
|
BOOST_REQUIRE(cc.before_commit());
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_cert_failed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_cert_failed);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
|
|
||||||
// Rollback sequence
|
// Rollback sequence
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -314,26 +305,19 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_uncertified
|
|||||||
//
|
//
|
||||||
// Test a transaction which gets BF aborted before after_statement.
|
// Test a transaction which gets BF aborted before after_statement.
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_after_statement)
|
BOOST_FIXTURE_TEST_CASE(
|
||||||
|
transaction_context_1pc_bf_during_before_after_statement,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
|
|
||||||
trrep_mock::bf_abort_unordered(cc, tc);
|
trrep_mock::bf_abort_unordered(cc);
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
@ -344,19 +328,12 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_after_statement)
|
|||||||
// Test a 1PC transaction which gets BF aborted during before_commit via
|
// Test a 1PC transaction which gets BF aborted during before_commit via
|
||||||
// provider after the write set was ordered and certified.
|
// provider after the write set was ordered and certified.
|
||||||
//
|
//
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_certified)
|
BOOST_FIXTURE_TEST_CASE(
|
||||||
|
transaction_context_1pc_bf_during_before_commit_certified,
|
||||||
|
replicating_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc, trrep::client_id(1), trrep::client_context::m_replicating);
|
|
||||||
trrep::transaction_context& tc(cc.transaction());
|
|
||||||
|
|
||||||
// Verify initial state
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
|
||||||
|
|
||||||
// Start a new transaction with ID 1
|
// Start a new transaction with ID 1
|
||||||
tc.start_transaction(1);
|
cc.start_transaction(1);
|
||||||
BOOST_REQUIRE(tc.active());
|
BOOST_REQUIRE(tc.active());
|
||||||
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
BOOST_REQUIRE(tc.id() == trrep::transaction_id(1));
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing);
|
||||||
@ -364,49 +341,35 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_certified)
|
|||||||
trrep_mock::bf_abort_provider(sc, tc, 1);
|
trrep_mock::bf_abort_provider(sc, tc, 1);
|
||||||
|
|
||||||
// Run before commit
|
// Run before commit
|
||||||
BOOST_REQUIRE(tc.before_commit());
|
BOOST_REQUIRE(cc.before_commit());
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == true);
|
BOOST_REQUIRE(tc.ordered() == true);
|
||||||
|
|
||||||
// Rollback sequence
|
// Rollback sequence
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_must_replay);
|
||||||
|
|
||||||
// Cleanup after statement
|
// Cleanup after statement
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.ordered() == false);
|
BOOST_REQUIRE(tc.ordered() == false);
|
||||||
BOOST_REQUIRE(tc.certified() == false);
|
BOOST_REQUIRE(tc.certified() == false);
|
||||||
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_1pc_applying)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_1pc_applying,
|
||||||
|
applying_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
BOOST_REQUIRE(cc.before_commit() == 0);
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc,
|
|
||||||
trrep::client_id(1),
|
|
||||||
trrep::client_context::m_applier);
|
|
||||||
trrep::transaction_context& tc(trrep_mock::start_applying_transaction(
|
|
||||||
cc, 1, 1,
|
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.start_transaction() == 0);
|
|
||||||
BOOST_REQUIRE(tc.active() == true);
|
|
||||||
BOOST_REQUIRE(tc.certified() == true);
|
|
||||||
BOOST_REQUIRE(tc.ordered() == true);
|
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.before_commit() == 0);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
BOOST_REQUIRE(tc.ordered_commit() == 0);
|
BOOST_REQUIRE(cc.ordered_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
||||||
BOOST_REQUIRE(tc.after_commit() == 0);
|
BOOST_REQUIRE(cc.after_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
||||||
@ -419,54 +382,45 @@ BOOST_AUTO_TEST_CASE(transaction_context_2pc_applying)
|
|||||||
trrep::mock_client_context cc(sc,
|
trrep::mock_client_context cc(sc,
|
||||||
trrep::client_id(1),
|
trrep::client_id(1),
|
||||||
trrep::client_context::m_applier);
|
trrep::client_context::m_applier);
|
||||||
trrep::transaction_context& tc(trrep_mock::start_applying_transaction(
|
|
||||||
|
BOOST_REQUIRE(cc.before_command() == 0);
|
||||||
|
BOOST_REQUIRE(cc.before_statement() == 0);
|
||||||
|
|
||||||
|
trrep_mock::start_applying_transaction(
|
||||||
cc, 1, 1,
|
cc, 1, 1,
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END);
|
||||||
|
const trrep::transaction_context& tc(cc.transaction());
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(tc.start_transaction() == 0);
|
BOOST_REQUIRE(cc.start_transaction() == 0);
|
||||||
BOOST_REQUIRE(tc.active() == true);
|
BOOST_REQUIRE(tc.active() == true);
|
||||||
BOOST_REQUIRE(tc.certified() == true);
|
BOOST_REQUIRE(tc.certified() == true);
|
||||||
BOOST_REQUIRE(tc.ordered() == true);
|
BOOST_REQUIRE(tc.ordered() == true);
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.before_prepare() == 0);
|
BOOST_REQUIRE(cc.before_prepare() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_preparing);
|
||||||
BOOST_REQUIRE(tc.after_prepare() == 0);
|
BOOST_REQUIRE(cc.after_prepare() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
BOOST_REQUIRE(tc.before_commit() == 0);
|
BOOST_REQUIRE(cc.before_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committing);
|
||||||
BOOST_REQUIRE(tc.ordered_commit() == 0);
|
BOOST_REQUIRE(cc.ordered_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_ordered_commit);
|
||||||
BOOST_REQUIRE(tc.after_commit() == 0);
|
BOOST_REQUIRE(cc.after_commit() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_committed);
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(transaction_context_applying_rollback)
|
BOOST_FIXTURE_TEST_CASE(transaction_context_applying_rollback,
|
||||||
|
applying_client_fixture)
|
||||||
{
|
{
|
||||||
trrep::mock_server_context sc("s1", "s1",
|
BOOST_REQUIRE(cc.before_rollback() == 0);
|
||||||
trrep::server_context::rm_sync);
|
|
||||||
trrep::mock_client_context cc(sc,
|
|
||||||
trrep::client_id(1),
|
|
||||||
trrep::client_context::m_applier);
|
|
||||||
trrep::transaction_context& tc(trrep_mock::start_applying_transaction(
|
|
||||||
cc, 1, 1,
|
|
||||||
WSREP_FLAG_TRX_START | WSREP_FLAG_TRX_END));
|
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
|
||||||
BOOST_REQUIRE(tc.start_transaction() == 0);
|
|
||||||
BOOST_REQUIRE(tc.active() == true);
|
|
||||||
BOOST_REQUIRE(tc.certified() == true);
|
|
||||||
BOOST_REQUIRE(tc.ordered() == true);
|
|
||||||
|
|
||||||
BOOST_REQUIRE(tc.before_rollback() == 0);
|
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborting);
|
||||||
BOOST_REQUIRE(tc.after_rollback() == 0);
|
BOOST_REQUIRE(cc.after_rollback() == 0);
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
BOOST_REQUIRE(tc.after_statement() == 0);
|
cc.after_statement();
|
||||||
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_aborted);
|
||||||
BOOST_REQUIRE(tc.active() == false);
|
BOOST_REQUIRE(tc.active() == false);
|
||||||
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
BOOST_REQUIRE(cc.current_error() == trrep::e_success);
|
||||||
|
Reference in New Issue
Block a user