mirror of https://gitee.com/bigwinds/arangodb
added explicit locking
This commit is contained in:
parent
8a6225865f
commit
44f2d05b4c
|
@ -66,7 +66,7 @@ namespace triagens {
|
|||
TRI_aql_context_t* const context) :
|
||||
Transaction<T>(vocbase, resolver) {
|
||||
|
||||
this->addHint(TRI_TRANSACTION_HINT_MANAGE_LOCKS);
|
||||
this->addHint(TRI_TRANSACTION_HINT_IMPLICIT_LOCK);
|
||||
|
||||
TRI_vector_pointer_t* collections = &context->_collections;
|
||||
|
||||
|
|
|
@ -349,10 +349,7 @@ namespace triagens {
|
|||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if ((this->status() == TRI_TRANSACTION_RUNNING && ! this->isEmbedded()) ||
|
||||
this->status() == TRI_TRANSACTION_COMMITTED ||
|
||||
this->status() == TRI_TRANSACTION_ABORTED ||
|
||||
this->status() == TRI_TRANSACTION_FINISHED) {
|
||||
if (this->status() != TRI_TRANSACTION_RUNNING) {
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
@ -361,14 +358,7 @@ namespace triagens {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (type == TRI_TRANSACTION_READ) {
|
||||
primary->beginRead(primary);
|
||||
}
|
||||
else {
|
||||
primary->beginWrite(primary);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
return TRI_LockCollectionTransaction(this->_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -381,10 +371,7 @@ namespace triagens {
|
|||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if ((this->status() == TRI_TRANSACTION_RUNNING && ! this->isEmbedded()) ||
|
||||
this->status() == TRI_TRANSACTION_COMMITTED ||
|
||||
this->status() == TRI_TRANSACTION_ABORTED ||
|
||||
this->status() == TRI_TRANSACTION_FINISHED) {
|
||||
if (this->status() != TRI_TRANSACTION_RUNNING) {
|
||||
return TRI_ERROR_TRANSACTION_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
@ -392,15 +379,8 @@ namespace triagens {
|
|||
// locking is a no-op in embedded transactions
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (type == TRI_TRANSACTION_READ) {
|
||||
primary->endRead(primary);
|
||||
}
|
||||
else {
|
||||
primary->endWrite(primary);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
||||
return TRI_UnlockCollectionTransaction(this->_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace triagens {
|
|||
const vector<string>& writeCollections) :
|
||||
Transaction<T>(vocbase, resolver) {
|
||||
|
||||
this->addHint(TRI_TRANSACTION_HINT_MANAGE_LOCKS);
|
||||
this->addHint(TRI_TRANSACTION_HINT_IMPLICIT_LOCK);
|
||||
|
||||
for (size_t i = 0; i < readCollections.size(); ++i) {
|
||||
this->addCollection(readCollections[i], TRI_TRANSACTION_READ);
|
||||
|
|
|
@ -533,6 +533,60 @@ static void FreeCollection (TRI_transaction_collection_t* collection) {
|
|||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lock a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int LockCollection (TRI_transaction_collection_t* collection,
|
||||
const TRI_transaction_type_e type) {
|
||||
TRI_primary_collection_t* primary;
|
||||
|
||||
assert(collection != NULL);
|
||||
assert(collection->_collection != NULL);
|
||||
assert(collection->_collection->_collection != NULL);
|
||||
assert(collection->_locked == false);
|
||||
|
||||
primary = collection->_collection->_collection;
|
||||
|
||||
if (type == TRI_TRANSACTION_READ) {
|
||||
primary->beginRead(primary);
|
||||
}
|
||||
else {
|
||||
primary->beginWrite(primary);
|
||||
}
|
||||
|
||||
collection->_locked = true;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unlock a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int UnlockCollection (TRI_transaction_collection_t* collection,
|
||||
const TRI_transaction_type_e type) {
|
||||
TRI_primary_collection_t* primary;
|
||||
|
||||
assert(collection != NULL);
|
||||
assert(collection->_collection != NULL);
|
||||
assert(collection->_collection->_collection != NULL);
|
||||
assert(collection->_locked == true);
|
||||
|
||||
primary = collection->_collection->_collection;
|
||||
|
||||
if (type == TRI_TRANSACTION_READ) {
|
||||
primary->endRead(primary);
|
||||
}
|
||||
else {
|
||||
primary->endWrite(primary);
|
||||
}
|
||||
|
||||
collection->_locked = false;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a global instance for the collection
|
||||
/// this function will create a global instance if it does not yet exist
|
||||
|
@ -599,17 +653,12 @@ static int UseCollections (TRI_transaction_t* const trx) {
|
|||
collection->_globalLock = true;
|
||||
}
|
||||
|
||||
if ((trx->_hints & (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_MANAGE_LOCKS) != 0) {
|
||||
TRI_primary_collection_t* primary = (TRI_primary_collection_t*) collection->_collection->_collection;
|
||||
if ((trx->_hints & (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_IMPLICIT_LOCK) != 0) {
|
||||
int res = LockCollection(collection, collection->_type);
|
||||
|
||||
if (collection->_type == TRI_TRANSACTION_WRITE) {
|
||||
primary->beginWrite(primary);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
else if (collection->_type == TRI_TRANSACTION_READ) {
|
||||
primary->beginRead(primary);
|
||||
}
|
||||
|
||||
collection->_locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,18 +688,8 @@ static int ReleaseCollections (TRI_transaction_t* const trx) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (collection->_locked &&
|
||||
(trx->_hints & (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_MANAGE_LOCKS) != 0) {
|
||||
|
||||
TRI_primary_collection_t* primary = (TRI_primary_collection_t*) collection->_collection->_collection;
|
||||
if (collection->_type == TRI_TRANSACTION_WRITE) {
|
||||
primary->endWrite(primary);
|
||||
}
|
||||
else if (collection->_type == TRI_TRANSACTION_READ) {
|
||||
primary->endRead(primary);
|
||||
}
|
||||
|
||||
collection->_locked = false;
|
||||
if (collection->_locked) {
|
||||
UnlockCollection(collection, collection->_type);
|
||||
}
|
||||
|
||||
if (collection->_type == TRI_TRANSACTION_WRITE && collection->_globalLock) {
|
||||
|
@ -971,6 +1010,58 @@ void TRI_FreeTransaction (TRI_transaction_t* const trx) {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief request a lock for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_LockCollectionTransaction (TRI_transaction_t* const trx,
|
||||
const TRI_transaction_cid_t cid,
|
||||
const TRI_transaction_type_e type) {
|
||||
size_t i, n;
|
||||
|
||||
n = trx->_collections._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_transaction_collection_t* collection = TRI_AtVectorPointer(&trx->_collections, i);
|
||||
|
||||
if (collection->_collection == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collection->_cid == cid) {
|
||||
return LockCollection(collection, type);
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief request an unlock for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_UnlockCollectionTransaction (TRI_transaction_t* const trx,
|
||||
const TRI_transaction_cid_t cid,
|
||||
const TRI_transaction_type_e type) {
|
||||
size_t i, n;
|
||||
|
||||
n = trx->_collections._length;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_transaction_collection_t* collection = TRI_AtVectorPointer(&trx->_collections, i);
|
||||
|
||||
if (collection->_collection == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collection->_cid == cid) {
|
||||
return UnlockCollection(collection, type);
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return whether the transaction consists only of a single operation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -303,7 +303,7 @@ typedef uint32_t TRI_transaction_hint_t;
|
|||
typedef enum {
|
||||
TRI_TRANSACTION_HINT_NONE = 0,
|
||||
TRI_TRANSACTION_HINT_SINGLE_OPERATION = 1,
|
||||
TRI_TRANSACTION_HINT_MANAGE_LOCKS = 2
|
||||
TRI_TRANSACTION_HINT_IMPLICIT_LOCK = 2
|
||||
}
|
||||
TRI_transaction_hint_e;
|
||||
|
||||
|
@ -401,6 +401,22 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const,
|
|||
const TRI_transaction_cid_t,
|
||||
const TRI_transaction_type_e);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief request a lock for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_LockCollectionTransaction (TRI_transaction_t* const,
|
||||
const TRI_transaction_cid_t,
|
||||
const TRI_transaction_type_e);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief request an unlock for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_UnlockCollectionTransaction (TRI_transaction_t* const,
|
||||
const TRI_transaction_cid_t,
|
||||
const TRI_transaction_type_e);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief start a transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue