1
0
Fork 0

added transaction commit hooks

This commit is contained in:
jsteemann 2017-05-04 02:00:40 +02:00
parent b65b1a3717
commit a15cf5bce6
2 changed files with 43 additions and 0 deletions

View File

@ -742,6 +742,8 @@ Result transaction::Methods::commit() {
return TRI_ERROR_TRANSACTION_INTERNAL; return TRI_ERROR_TRANSACTION_INTERNAL;
} }
CallbackInvoker invoker(this);
if (_state->isCoordinator()) { if (_state->isCoordinator()) {
if (_state->isTopLevelTransaction()) { if (_state->isTopLevelTransaction()) {
_state->updateStatus(transaction::Status::COMMITTED); _state->updateStatus(transaction::Status::COMMITTED);
@ -759,6 +761,8 @@ Result transaction::Methods::abort() {
return TRI_ERROR_TRANSACTION_INTERNAL; return TRI_ERROR_TRANSACTION_INTERNAL;
} }
CallbackInvoker invoker(this);
if (_state->isCoordinator()) { if (_state->isCoordinator()) {
if (_state->isTopLevelTransaction()) { if (_state->isTopLevelTransaction()) {
_state->updateStatus(transaction::Status::ABORTED); _state->updateStatus(transaction::Status::ABORTED);
@ -2885,3 +2889,16 @@ Result transaction::Methods::resolveId(char const* handle, size_t length,
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
/// @brief invoke a callback method when a transaction has finished
void transaction::CallbackInvoker::invoke() noexcept {
if (!_trx->_onFinish) {
return;
}
try {
_trx->_onFinish(_trx);
} catch (...) {
// we must not propagate exceptions from here
}
}

View File

@ -64,6 +64,7 @@ class BaseEngine;
} }
namespace transaction { namespace transaction {
class CallbackInvoker;
class Context; class Context;
} }
@ -81,6 +82,7 @@ namespace transaction {
class Methods { class Methods {
friend class traverser::BaseEngine; friend class traverser::BaseEngine;
friend class CallbackInvoker;
public: public:
@ -141,6 +143,9 @@ class Methods {
ANY ANY
}; };
/// @brief register a callback for transaction commit or abort
void registerCallback(std::function<void(arangodb::transaction::Methods* trx)> const& onFinish) { _onFinish = onFinish; }
/// @brief return database of transaction /// @brief return database of transaction
TRI_vocbase_t* vocbase() const; TRI_vocbase_t* vocbase() const;
inline std::string const& databaseName() const { return vocbase()->name(); } inline std::string const& databaseName() const { return vocbase()->name(); }
@ -168,6 +173,9 @@ class Methods {
/// @brief get the status of the transaction /// @brief get the status of the transaction
Status status() const; Status status() const;
/// @brief get the status of the transaction, as a string
char const* statusString() const { return transaction::statusString(status()); }
/// @brief begin the transaction /// @brief begin the transaction
Result begin(); Result begin();
@ -556,11 +564,29 @@ class Methods {
/// @brief transaction hints /// @brief transaction hints
transaction::Hints _localHints; transaction::Hints _localHints;
/// @brief name-to-cid lookup cache for last collection seen
struct { struct {
TRI_voc_cid_t cid = 0; TRI_voc_cid_t cid = 0;
std::string name; std::string name;
} }
_collectionCache; _collectionCache;
/// @brief optional callback function that will be called on transaction
/// commit or abort
std::function<void(arangodb::transaction::Methods* trx)> _onFinish;
};
class CallbackInvoker {
public:
explicit CallbackInvoker(transaction::Methods* trx) : _trx(trx) {}
~CallbackInvoker() {
invoke();
}
void invoke() noexcept;
private:
transaction::Methods* _trx;
}; };
} }