1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-30 07:23:07 +03:00

Support for detaching prepared XA transactions

Add support for detaching XA transactions. This is useful for handling
the case where the DBMS client has a transaction in prepared state and
disconnects. Before disconnect, the DBMS calls the newly introduced
client_state::xa_detach(), to cleanup the local transaction and
convert it to a high priority transaction. The DBMS may later attempt
to terminate the transaction through client_state::commit_by_xid() or
client_state::rollback_by_xid().

Also in this patch:

- Fix client_state::close() so that it does not rollback transactions
  in prepared state
- Changed class wsrep::xid representation to hold enough information
  so that DBMS can convert to its native representation
- Fix potential infinite loop in
  server_state::find_streaming_applier(wsrep:xid&)
- Append SR keys on prepare fragment and make it pa_unsafe
- Handle one phase commit (simply fall back to two phase)
- Do not rollback prepared streaming clients in
  server_state::close_orphaned_transactions()
This commit is contained in:
Daniele Sciascia
2020-03-25 15:40:24 +01:00
parent 2da6e4894e
commit 965642eded
9 changed files with 167 additions and 29 deletions

View File

@ -21,23 +21,80 @@
#define WSREP_XID_HPP
#include <iosfwd>
#include <string>
#include "buffer.hpp"
namespace wsrep
{
class xid
{
public:
xid() : xid_() { }
xid(const std::string& str) : xid_(str) { }
xid(const char* s) : xid_(s) { }
bool empty() const { return xid_.empty(); }
void clear() { xid_.clear(); }
bool operator==(const xid& other) const { return xid_ == other.xid_; }
xid()
: format_id_(-1)
, gtrid_len_(0)
, bqual_len_(0)
, data_()
{ }
xid(long format_id, long gtrid_len,
long bqual_len, const char* data)
: format_id_(format_id)
, gtrid_len_(gtrid_len)
, bqual_len_(bqual_len)
, data_()
{
const long len = gtrid_len_ + bqual_len_;
if (len > 0)
{
data_.push_back(data, data + len);
}
}
xid(const xid& xid)
: format_id_(xid.format_id_)
, gtrid_len_(xid.gtrid_len_)
, bqual_len_(xid.bqual_len_)
, data_(xid.data_)
{ }
bool is_null() const
{
return format_id_ == -1;
}
void clear()
{
format_id_ = -1;
data_.clear();
}
xid& operator= (const xid& other)
{
format_id_ = other.format_id_;
gtrid_len_ = other.gtrid_len_;
bqual_len_ = other.bqual_len_;
data_ = other.data_;
return *this;
}
bool operator==(const xid& other) const
{
if (format_id_ != other.format_id_ ||
gtrid_len_ != other.gtrid_len_ ||
bqual_len_ != other.bqual_len_ ||
data_.size() != other.data_.size())
{
return false;
}
return data_ == other.data_;
}
friend std::string to_string(const wsrep::xid& xid);
friend std::ostream& operator<<(std::ostream& os, const wsrep::xid& xid);
private:
std::string xid_;
protected:
long format_id_;
long gtrid_len_;
long bqual_len_;
mutable_buffer data_;
};
std::string to_string(const wsrep::xid& xid);