Make transaction thread-safe
Reviewers: dgleich Reviewed By: dgleich Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1223
This commit is contained in:
parent
46b8a91a2f
commit
16853e5b8a
@ -1,10 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
#include "storage/locking/lock_status.hpp"
|
#include "storage/locking/lock_status.hpp"
|
||||||
#include "storage/locking/record_lock.hpp"
|
#include "storage/locking/record_lock.hpp"
|
||||||
|
#include "threading/sync/spinlock.hpp"
|
||||||
#include "transactions/type.hpp"
|
#include "transactions/type.hpp"
|
||||||
|
|
||||||
namespace tx {
|
namespace tx {
|
||||||
@ -55,13 +58,26 @@ class LockStore {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void Take(RecordLock *lock, const tx::Transaction &tx, tx::Engine &engine) {
|
void Take(RecordLock *lock, const tx::Transaction &tx, tx::Engine &engine) {
|
||||||
locks_.emplace_back(LockHolder(lock, tx, engine));
|
// Creating a lock holder locks the version list to the given transaction.
|
||||||
|
// Note that it's an op that can take a long time (if there are multiple
|
||||||
|
// transactions trying to lock.
|
||||||
|
LockHolder holder{lock, tx, engine};
|
||||||
|
|
||||||
|
// This guard prevents the same transaction from concurrent modificaton of
|
||||||
|
// locks_. This can only happen in distributed memgraph, when there are
|
||||||
|
// multiple edits coming to the same worker in the same transaction at the
|
||||||
|
// same time. IMPORTANT: This guard must come after LockHolder construction,
|
||||||
|
// as that potentially takes a long time and this guard only needs to
|
||||||
|
// protect locks_ update.
|
||||||
|
std::lock_guard<SpinLock> guard{locks_lock_};
|
||||||
|
locks_.emplace_back(std::move(holder));
|
||||||
if (!locks_.back().active()) {
|
if (!locks_.back().active()) {
|
||||||
locks_.pop_back();
|
locks_.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SpinLock locks_lock_;
|
||||||
std::vector<LockHolder> locks_;
|
std::vector<LockHolder> locks_;
|
||||||
};
|
};
|
||||||
} // namespace tx
|
} // namespace tx
|
||||||
|
Loading…
Reference in New Issue
Block a user