1
0
Fork 0

some cleanup in transaction code

This commit is contained in:
Jan Steemann 2013-03-20 18:44:29 +01:00
parent 79ceda1d51
commit 26af2995db
8 changed files with 396 additions and 383 deletions

View File

@ -28,12 +28,6 @@
#ifndef TRIAGENS_UTILS_EMBEDDABLE_TRANSACTION_H
#define TRIAGENS_UTILS_EMBEDDABLE_TRANSACTION_H 1
#include "VocBase/transaction.h"
#include "V8/v8-globals.h"
#include <v8.h>
namespace triagens {
namespace arango {
@ -59,14 +53,8 @@ namespace triagens {
/// @brief create the transaction
////////////////////////////////////////////////////////////////////////////////
EmbeddableTransaction () : _trx(0) {
TRI_v8_global_t* v8g;
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
if (v8g->_currentTransaction == 0) {
_previous = (TRI_transaction_t*) v8g->_currentTransaction;
}
EmbeddableTransaction () :
C() {
}
////////////////////////////////////////////////////////////////////////////////
@ -99,52 +87,6 @@ namespace triagens {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free the transaction
////////////////////////////////////////////////////////////////////////////////
int freeTransaction () {
if (this->isEmbedded()) {
return TRI_ERROR_NO_ERROR;
}
if (_trx != 0) {
this->unregisterTransaction();
TRI_FreeTransaction(_trx);
_trx = 0;
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief previous transaction, if any
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* _previous;
////////////////////////////////////////////////////////////////////////////////
/// @brief used transaction
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* _trx;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -80,19 +80,10 @@ namespace triagens {
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the transaction is embedded
/// @brief return the parent transaction (none in our case)
////////////////////////////////////////////////////////////////////////////////
inline bool isEmbedded () const {
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the parent transaction if any
////////////////////////////////////////////////////////////////////////////////
inline TRI_transaction_t* getParent () const {
assert(false);
inline TRI_transaction_t* getParentTransaction () const {
return 0;
}

View File

@ -109,7 +109,7 @@ namespace triagens {
inline TRI_primary_collection_t* primaryCollection () {
assert(this->_cid > 0);
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, this->_cid, TRI_TRANSACTION_READ);
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->getTrx(), this->_cid, TRI_TRANSACTION_READ);
assert(collection != 0);
assert(collection->_collection != 0);

View File

@ -28,8 +28,6 @@
#ifndef TRIAGENS_UTILS_STANDALONE_TRANSACTION_H
#define TRIAGENS_UTILS_STANDALONE_TRANSACTION_H 1
#include "VocBase/transaction.h"
namespace triagens {
namespace arango {
@ -56,8 +54,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
StandaloneTransaction () :
C(),
_trx(0) {
C() {
}
////////////////////////////////////////////////////////////////////////////////
@ -90,27 +87,6 @@ namespace triagens {
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief used transaction
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* _trx;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -87,18 +87,18 @@ namespace triagens {
Transaction (TRI_vocbase_t* const vocbase,
const triagens::arango::CollectionNameResolver& resolver) :
T(),
_vocbase(vocbase),
_resolver(resolver),
_trx(0),
_setupError(TRI_ERROR_NO_ERROR),
_nestingLevel(0),
_readOnly(true),
_hints(0) {
_hints(0),
_vocbase(vocbase),
_resolver(resolver) {
assert(_vocbase != 0);
TRI_ASSERT_DEBUG(_vocbase != 0);
int res = createTransaction();
if (res != TRI_ERROR_NO_ERROR) {
_setupError = res;
}
// normally this will return TRI_ERROR_NO_ERROR
this->_setupError = this->setupTransaction();
}
////////////////////////////////////////////////////////////////////////////////
@ -106,12 +106,15 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
virtual ~Transaction () {
if (this->_trx != 0 && ! this->isEmbedded()) {
if (this->status() == TRI_TRANSACTION_RUNNING) {
// auto abort
this->abort();
}
freeTransaction();
if (_trx == 0) {
return;
}
if (isEmbeddedTransaction()) {
destroyEmbedded();
}
else {
destroyToplevel();
}
}
@ -131,119 +134,11 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief begin the transaction
/// @brief whether or not the transaction is embedded
////////////////////////////////////////////////////////////////////////////////
int begin () {
if (this->_trx == 0) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded()) {
if (this->status() == TRI_TRANSACTION_RUNNING) {
if (this->_setupError != TRI_ERROR_NO_ERROR) {
return this->_setupError;
}
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->_setupError != TRI_ERROR_NO_ERROR) {
return this->_setupError;
}
if (this->status() != TRI_TRANSACTION_CREATED) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
return TRI_StartTransaction(this->_trx, _hints);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief commit / finish the transaction
////////////////////////////////////////////////////////////////////////////////
int commit () {
if (this->_trx == 0 || this->status() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded()) {
// return instantly if the transaction is embedded
return TRI_ERROR_NO_ERROR;
}
int res;
if (this->_trx->_type == TRI_TRANSACTION_READ) {
// a read transaction just finishes
res = TRI_FinishTransaction(this->_trx);
}
else {
// a write transaction commits
res = TRI_CommitTransaction(this->_trx);
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abort the transaction
////////////////////////////////////////////////////////////////////////////////
int abort () {
if (this->_trx == 0 || this->status() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded() && this->isReadOnlyTransaction()) {
// return instantly if the transaction is embedded
return TRI_ERROR_NO_ERROR;
}
int res = TRI_AbortTransaction(this->_trx);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finish a transaction, based on the previous state
////////////////////////////////////////////////////////////////////////////////
int finish (const int errorNumber) {
if (this->_trx == 0 || this->status() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
int res;
if (errorNumber == TRI_ERROR_NO_ERROR) {
// there was no previous error, so we'll commit
res = this->commit();
}
else {
// there was a previous error, so we'll abort
this->abort();
// return original error number
res = errorNumber;
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the status of the transaction
////////////////////////////////////////////////////////////////////////////////
inline TRI_transaction_status_e status () const {
if (this->_trx != 0) {
return this->_trx->_status;
}
return TRI_TRANSACTION_UNDEFINED;
inline bool isEmbeddedTransaction () const {
return (_nestingLevel > 0);
}
////////////////////////////////////////////////////////////////////////////////
@ -251,7 +146,99 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
inline bool isReadOnlyTransaction () const {
return _readOnly;
return this->_readOnly;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the status of the transaction
////////////////////////////////////////////////////////////////////////////////
inline TRI_transaction_status_e getStatus () const {
if (_trx != 0) {
return _trx->_status;
}
return TRI_TRANSACTION_UNDEFINED;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief begin the transaction
////////////////////////////////////////////////////////////////////////////////
int begin () {
if (_trx == 0) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (_setupError != TRI_ERROR_NO_ERROR) {
return _setupError;
}
LOGGER_TRACE("beginning transaction");
if (isEmbeddedTransaction()) {
return beginEmbedded();
}
else {
return beginToplevel();
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief commit / finish the transaction
////////////////////////////////////////////////////////////////////////////////
int commit () {
if (_trx == 0 || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
LOGGER_TRACE("committing transaction");
if (isEmbeddedTransaction()) {
return commitEmbedded();
}
else {
return commitToplevel();
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abort the transaction
////////////////////////////////////////////////////////////////////////////////
int abort () {
if (_trx == 0 || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
LOGGER_TRACE("aborting transaction");
if (isEmbeddedTransaction()) {
return abortEmbedded();
}
else {
return abortToplevel();
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finish a transaction (commit or abort), based on the previous state
////////////////////////////////////////////////////////////////////////////////
int finish (const int errorNumber) {
if (errorNumber == TRI_ERROR_NO_ERROR) {
// there was no previous error, so we'll commit
return this->commit();
}
// there was a previous error, so we'll abort
this->abort();
// return original error number
return errorNumber;
}
////////////////////////////////////////////////////////////////////////////////
@ -259,8 +246,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
void dump () {
if (this->_trx != 0) {
TRI_DumpTransaction(this->_trx);
if (_trx != 0) {
TRI_DumpTransaction(this->__trx);
}
}
@ -285,35 +272,37 @@ namespace triagens {
int addCollection (TRI_transaction_cid_t cid,
TRI_transaction_type_e type) {
if (this->_trx == 0) {
if (_trx == 0) {
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) {
const TRI_transaction_status_e status = getStatus();
if ((status == TRI_TRANSACTION_RUNNING && ! this->isEmbeddedTransaction()) ||
status == TRI_TRANSACTION_COMMITTED ||
status == TRI_TRANSACTION_ABORTED ||
status == TRI_TRANSACTION_FINISHED) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (cid == 0) {
// invalid cid
return _setupError = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
return this->_setupError = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
if (type == TRI_TRANSACTION_WRITE) {
_readOnly = false;
this->_readOnly = false;
}
if (this->isEmbedded()) {
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, cid, type);
if (this->isEmbeddedTransaction()) {
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(_trx, cid, type);
if (collection == 0) {
// adding an unknown collection...
int res = TRI_ERROR_NO_ERROR;
if (type == TRI_TRANSACTION_READ && this->isReadOnlyTransaction()) {
res = TRI_AddDelayedReadCollectionTransaction(this->_trx, cid);
res = TRI_AddDelayedReadCollectionTransaction(_trx, cid);
}
else {
res = TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
@ -327,7 +316,7 @@ namespace triagens {
return TRI_ERROR_NO_ERROR;
}
int res = TRI_AddCollectionTransaction(this->_trx, cid, type);
int res = TRI_AddCollectionTransaction(_trx, cid, type);
if (res != TRI_ERROR_NO_ERROR) {
_setupError = res;
@ -365,20 +354,20 @@ namespace triagens {
int lockExplicit (TRI_primary_collection_t* const primary,
const TRI_transaction_type_e type) {
if (this->_trx == 0) {
if (_trx == 0) {
return TRI_ERROR_INTERNAL;
}
if (this->status() != TRI_TRANSACTION_RUNNING) {
if (getStatus() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded()) {
if (this->isEmbeddedTransaction()) {
// locking is a no-op in embedded transactions
return TRI_ERROR_NO_ERROR;
}
return TRI_LockCollectionTransaction(this->_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
return TRI_LockCollectionTransaction(_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
}
////////////////////////////////////////////////////////////////////////////////
@ -387,20 +376,20 @@ namespace triagens {
int unlockExplicit (TRI_primary_collection_t* const primary,
const TRI_transaction_type_e type) {
if (this->_trx == 0) {
if (_trx == 0) {
return TRI_ERROR_INTERNAL;
}
if (this->status() != TRI_TRANSACTION_RUNNING) {
if (getStatus() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded()) {
if (this->isEmbeddedTransaction()) {
// locking is a no-op in embedded transactions
return TRI_ERROR_NO_ERROR;
}
return TRI_UnlockCollectionTransaction(this->_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
return TRI_UnlockCollectionTransaction(_trx, (TRI_transaction_cid_t) primary->base._info._cid, type);
}
////////////////////////////////////////////////////////////////////////////////
@ -622,6 +611,7 @@ namespace triagens {
}
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json);
if (shaped == 0) {
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
@ -778,6 +768,15 @@ namespace triagens {
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the pointer to the C transaction struct
/// DEPRECATED
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* getTrx () {
return this->_trx;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -793,8 +792,178 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy an embedded transaction
////////////////////////////////////////////////////////////////////////////////
void destroyEmbedded () {
TRI_ASSERT_DEBUG(_nestingLevel > 0);
TRI_ASSERT_DEBUG(_trx->_nestingLevel > 0);
_trx->_nestingLevel--;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy a top-level transaction
////////////////////////////////////////////////////////////////////////////////
void destroyToplevel () {
TRI_ASSERT_DEBUG(_nestingLevel == 0);
TRI_ASSERT_DEBUG(_trx->_nestingLevel == 0);
if (getStatus() == TRI_TRANSACTION_RUNNING) {
// auto abort a running transaction
this->abort();
}
// free the data associated with the transaction
freeTransaction();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief begin an embedded transaction
////////////////////////////////////////////////////////////////////////////////
inline int beginEmbedded () {
if (getStatus() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief begin a top-level transaction
////////////////////////////////////////////////////////////////////////////////
inline int beginToplevel () {
if (getStatus() != TRI_TRANSACTION_CREATED) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
return TRI_StartTransaction(_trx, _hints);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief commit an embedded transaction
////////////////////////////////////////////////////////////////////////////////
inline int commitEmbedded () {
// return instantly if the transaction is embedded
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief commit a top-level transaction
////////////////////////////////////////////////////////////////////////////////
inline int commitToplevel () {
if (_trx->_type == TRI_TRANSACTION_READ) {
// a read transaction just finishes
return TRI_FinishTransaction(_trx);
}
// a write transaction commits
return TRI_CommitTransaction(_trx);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abort an embedded transaction
////////////////////////////////////////////////////////////////////////////////
inline int abortEmbedded () {
if (_readOnly) {
// return instantly if the transaction is embedded
return TRI_ERROR_NO_ERROR;
}
// real abort
return TRI_AbortTransaction(_trx);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abort a top-level transaction
////////////////////////////////////////////////////////////////////////////////
inline int abortToplevel () {
// real abort
return TRI_AbortTransaction(_trx);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief initialise the transaction
/// this will first check if the transaction is embedded in a parent
/// transaction. if not, it will create a transaction of its own
////////////////////////////////////////////////////////////////////////////////
int setupTransaction () {
// check in the context if we are running embedded
_trx = this->getParentTransaction();
if (_trx != 0) {
// yes, we are embedded
return setupEmbedded();
}
else {
return setupToplevel();
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set up an embedded transaction
////////////////////////////////////////////////////////////////////////////////
int setupEmbedded () {
_nestingLevel = ++_trx->_nestingLevel;
if (! this->isEmbeddable()) {
// we are embedded but this is disallowed...
LOGGER_WARNING("logic error. invalid nesting of transactions");
return TRI_ERROR_TRANSACTION_NESTED;
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set up a top-level transaction
////////////////////////////////////////////////////////////////////////////////
int setupToplevel () {
_nestingLevel = 0;
// we are not embedded. now start our own transaction
_trx = TRI_CreateTransaction(_vocbase->_transactionContext);
if (_trx == 0) {
return TRI_ERROR_OUT_OF_MEMORY;
}
// register the transaction in the context
return this->registerTransaction(_trx);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free transaction
////////////////////////////////////////////////////////////////////////////////
int freeTransaction () {
TRI_ASSERT_DEBUG(! isEmbeddedTransaction());
if (_trx != 0) {
this->unregisterTransaction();
TRI_FreeTransaction(_trx);
_trx = 0;
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the "_key" attribute from a JSON object
/// TODO: move out of this class
////////////////////////////////////////////////////////////////////////////////
int getKey (TRI_json_t const* json, TRI_voc_key_t* key) {
@ -807,6 +976,7 @@ namespace triagens {
// check _key is there
const TRI_json_t* k = TRI_LookupArrayJson((TRI_json_t*) json, "_key");
if (k == 0) {
return TRI_ERROR_NO_ERROR;
}
@ -818,55 +988,54 @@ namespace triagens {
// _key is there and a string
*key = k->_value._string.data;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create transaction
////////////////////////////////////////////////////////////////////////////////
int createTransaction () {
if (this->isEmbedded()) {
if (! this->isEmbeddable()) {
return TRI_ERROR_TRANSACTION_NESTED;
}
this->_trx = this->getParent();
if (this->_trx == 0) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
return TRI_ERROR_NO_ERROR;
}
this->_trx = TRI_CreateTransaction(_vocbase->_transactionContext, TRI_TRANSACTION_READ_REPEATABLE);
if (this->_trx == 0) {
return TRI_ERROR_OUT_OF_MEMORY;
}
this->registerTransaction(this->_trx);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free transaction
/// @}
////////////////////////////////////////////////////////////////////////////////
int freeTransaction () {
assert(! this->isEmbedded());
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
if (this->_trx != 0) {
this->unregisterTransaction();
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
TRI_FreeTransaction(this->_trx);
this->_trx = 0;
}
private:
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief the C transaction struct
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* _trx;
////////////////////////////////////////////////////////////////////////////////
/// @brief error that occurred on transaction initialisation (before begin())
////////////////////////////////////////////////////////////////////////////////
int _setupError;
////////////////////////////////////////////////////////////////////////////////
/// @brief how deep the transaction is down in a nested transaction structure
////////////////////////////////////////////////////////////////////////////////
int _nestingLevel;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the transaction is read-only
////////////////////////////////////////////////////////////////////////////////
bool _readOnly;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction hints
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_hint_t _hints;
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -895,39 +1064,6 @@ namespace triagens {
const CollectionNameResolver _resolver;
////////////////////////////////////////////////////////////////////////////////
/// @brief error that occurred on transaction initialisation (before begin())
////////////////////////////////////////////////////////////////////////////////
int _setupError;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the transaction is read-only
////////////////////////////////////////////////////////////////////////////////
bool _readOnly;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction hints
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_hint_t _hints;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -28,6 +28,8 @@
#ifndef TRIAGENS_UTILS_V8TRANSACTION_CONTEXT_H
#define TRIAGENS_UTILS_V8TRANSACTION_CONTEXT_H 1
#include <v8.h>
#include "V8/v8-globals.h"
namespace triagens {
@ -54,14 +56,7 @@ namespace triagens {
/// @brief create the context
////////////////////////////////////////////////////////////////////////////////
V8TransactionContext () : _previous(0) {
TRI_v8_global_t* v8g;
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
if (v8g->_currentTransaction != 0) {
_previous = (TRI_transaction_t*) v8g->_currentTransaction;
}
V8TransactionContext () {
}
////////////////////////////////////////////////////////////////////////////////
@ -87,28 +82,26 @@ namespace triagens {
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the transaction is embedded
/// @brief get parent transaction (if any)
////////////////////////////////////////////////////////////////////////////////
inline bool isEmbedded () const {
return _previous != 0;
}
inline TRI_transaction_t* getParentTransaction () const {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
////////////////////////////////////////////////////////////////////////////////
/// @brief return the parent transaction if any
////////////////////////////////////////////////////////////////////////////////
if (v8g->_currentTransaction != 0) {
return (TRI_transaction_t*) v8g->_currentTransaction;
}
inline TRI_transaction_t* getParent () const {
return _previous;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register the transaction in the context
////////////////////////////////////////////////////////////////////////////////
int registerTransaction (TRI_transaction_t* const trx) {
TRI_v8_global_t* v8g;
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
inline int registerTransaction (TRI_transaction_t* const trx) const {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8g->_currentTransaction = trx;
return TRI_ERROR_NO_ERROR;
@ -118,36 +111,14 @@ namespace triagens {
/// @brief unregister the transaction from the context
////////////////////////////////////////////////////////////////////////////////
int unregisterTransaction () {
TRI_v8_global_t* v8g;
inline int unregisterTransaction () const {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8g->_currentTransaction = 0;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief previous transaction
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* _previous;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1016,11 +1016,11 @@ static int RegisterTransaction (TRI_transaction_t* const trx) {
/// @brief create a new transaction container
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* TRI_CreateTransaction (TRI_transaction_context_t* const context,
const TRI_transaction_isolation_level_e isolationLevel) {
TRI_transaction_t* TRI_CreateTransaction (TRI_transaction_context_t* const context) {
TRI_transaction_t* trx;
trx = (TRI_transaction_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_t), false);
if (trx == NULL) {
// out of memory
return NULL;
@ -1031,8 +1031,8 @@ TRI_transaction_t* TRI_CreateTransaction (TRI_transaction_context_t* const conte
trx->_id._localId = 0;
trx->_status = TRI_TRANSACTION_CREATED;
trx->_type = TRI_TRANSACTION_READ;
trx->_isolationLevel = isolationLevel;
trx->_hints = 0;
trx->_nestingLevel = 0;
TRI_InitVectorPointer2(&trx->_collections, TRI_UNKNOWN_MEM_ZONE, 2);
@ -1117,6 +1117,7 @@ int TRI_UnlockCollectionTransaction (TRI_transaction_t* const trx,
n = trx->_collections._length;
// shouldn't this be in reverse order?
for (i = 0; i < n; ++i) {
TRI_transaction_collection_t* collection = TRI_AtVectorPointer(&trx->_collections, i);
@ -1132,6 +1133,7 @@ int TRI_UnlockCollectionTransaction (TRI_transaction_t* const trx,
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
/*
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the transaction consists only of a single operation
////////////////////////////////////////////////////////////////////////////////
@ -1139,7 +1141,9 @@ int TRI_UnlockCollectionTransaction (TRI_transaction_t* const trx,
bool TRI_IsSingleOperationTransaction (const TRI_transaction_t* const trx) {
return (trx->_hints & (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_SINGLE_OPERATION) != 0;
}
*/
/*
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the transaction spans multiple write collections
////////////////////////////////////////////////////////////////////////////////
@ -1171,6 +1175,7 @@ bool TRI_IsMultiCollectionWriteTransaction (const TRI_transaction_t* const trx)
return false;
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief return the local id of a transaction

View File

@ -84,17 +84,6 @@ typedef struct TRI_transaction_id_s {
}
TRI_transaction_id_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction isolation level
////////////////////////////////////////////////////////////////////////////////
typedef enum {
TRI_TRANSACTION_READ_UNCOMMITED = 1,
TRI_TRANSACTION_READ_COMMITTED = 2,
TRI_TRANSACTION_READ_REPEATABLE = 3
}
TRI_transaction_isolation_level_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction type
////////////////////////////////////////////////////////////////////////////////
@ -327,13 +316,13 @@ TRI_transaction_hint_e;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_transaction_s {
TRI_transaction_context_t* _context; // global context object
TRI_transaction_id_t _id; // id of transaction
TRI_transaction_type_e _type; // access type (read|write)
TRI_transaction_status_e _status; // current status
TRI_transaction_isolation_level_e _isolationLevel; // isolation level
TRI_vector_pointer_t _collections; // list of participating collections
TRI_transaction_hint_t _hints; // hints;
TRI_transaction_context_t* _context; // global context object
TRI_transaction_id_t _id; // id of transaction
TRI_transaction_type_e _type; // access type (read|write)
TRI_transaction_status_e _status; // current status
TRI_vector_pointer_t _collections; // list of participating collections
TRI_transaction_hint_t _hints; // hints;
int _nestingLevel;
}
TRI_transaction_t;
@ -354,8 +343,7 @@ TRI_transaction_t;
/// @brief create a new transaction container
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_t* TRI_CreateTransaction (TRI_transaction_context_t* const,
const TRI_transaction_isolation_level_e);
TRI_transaction_t* TRI_CreateTransaction (TRI_transaction_context_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief free a transaction container
@ -376,17 +364,21 @@ void TRI_FreeTransaction (TRI_transaction_t* const);
/// @{
////////////////////////////////////////////////////////////////////////////////
/*
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the transaction consists only of a single operation
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSingleOperationTransaction (const TRI_transaction_t* const);
*/
/*
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the transaction spans multiple write collections
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsMultiCollectionWriteTransaction (const TRI_transaction_t* const);
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief return the local id of a transaction