diff --git a/src/transaction.cpp b/src/transaction.cpp index 373452a1..2a015a14 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -1136,8 +1136,22 @@ int wsrep::transaction::commit_or_rollback_by_xid(const wsrep::xid& xid, if (!sa) { - assert(sa); - client_state_.override_error(wsrep::e_error_during_commit); + enum wsrep::provider::status status; + if (server_state.state() == wsrep::server_state::s_disconnected) + { + // The node has disconnected from the cluster, and has closed + // all streaming appliers. We can't tell if a transaction with + // corresponding xid exists. In any case, we can't do much + // while disconnected, the client should retry. + status = wsrep::provider::error_connection_failed; + } + else + { + // The xid never existed, or it was already committed or + // rolled back. + status = wsrep::provider::error_transaction_missing; + } + client_state_.override_error(wsrep::e_error_during_commit, status); return 1; } @@ -1517,6 +1531,8 @@ int wsrep::transaction::certify_fragment( flags(flags() | wsrep::provider::flag::implicit_deps); } + client_service_.debug_sync("wsrep_before_fragment_append"); + int ret(0); enum wsrep::client_error error(wsrep::e_success); enum wsrep::provider::status cert_ret(wsrep::provider::success); @@ -1535,14 +1551,21 @@ int wsrep::transaction::certify_fragment( // available to store the fragment. The fragment meta data // is updated after certification. wsrep::id server_id(client_state_.server_state().id()); - assert(server_id.is_undefined() == false); - if (storage_service.start_transaction(ws_handle_) || + if (server_id.is_undefined()) + { + // we can't append a fragment with undefined server_id + // server has disconnected? + ret = 1; + error = wsrep::e_append_fragment_error; + } + + if (!ret && (storage_service.start_transaction(ws_handle_) || storage_service.append_fragment( server_id, id(), flags(), wsrep::const_buffer(data.data(), data.size()), - xid())) + xid()))) { ret = 1; error = wsrep::e_append_fragment_error;