Example #1
0
 internal void Begin()
 {
     try
     {
         if (_state == TransactionState.Active)
         {
             throw new InvalidOperationException("Transaction is already active");
         }
         CheckThread();
         if (_threadFlag != null)
         {
             throw new InvalidOperationException("Nested transactions are not allowed!");
         }
         _threadFlag = true;
         _startTime  = Clock.CurrentTimeMillis();
         var request = TransactionCreateCodec.EncodeRequest(_options.GetTimeoutMillis(), _options.GetDurability(),
                                                            (int)_options.GetTransactionType(), _threadId);
         var response = Invoke(request);
         _txnId = TransactionCreateCodec.DecodeResponse(response).Response;
         _state = TransactionState.Active;
     }
     catch (Exception e)
     {
         _threadFlag = null;
         throw ExceptionUtil.Rethrow(e);
     }
 }
Example #2
0
        /// <summary>
        /// Begins the transaction.
        /// </summary>
        public async Task BeginAsync()
        {
            if (State != TransactionState.None)
            {
                throw new InvalidOperationException("The transaction context is already involved in a transaction.");
            }

            var asyncContext = AsyncContext.Current;

            lock (_inTransactionMutex)
            {
                // this is used to prevent an asynchronous context from being in multiple (thus nested) transactions,
                // it was implemented, before async, via a [ThreadStatic] boolean (when everything was bound to
                // threads) which cannot be appropriate anymore. instead we move it to the async context.

                if (asyncContext.InTransaction)
                {
                    throw new InvalidOperationException("Nested transactions are not supported.");
                }
                asyncContext.InTransaction = true;
            }

            _connection = _cluster.Members.GetRandomConnection();
            if (_connection == null)
            {
                throw _cluster.State.ThrowClientOfflineException();
            }

            _threadId = ContextId;
            //_startTime = Clock.Milliseconds;

            HConsole.WriteLine(this, $"Begin transaction on context #{ContextId}");

            try
            {
                // codec wants 0 for server config, -1 for infinite (?)
                var timeoutMs = _options.Timeout.RoundedMilliseconds(false);

                var requestMessage  = TransactionCreateCodec.EncodeRequest(timeoutMs, _options.Durability, (int)_options.Type, ContextId);
                var responseMessage = await _cluster.Messaging.SendToMemberAsync(requestMessage, _connection).CfAwait();

                TransactionId = TransactionCreateCodec.DecodeResponse(responseMessage).Response;
                State         = TransactionState.Active;
            }
            catch
            {
                lock (_inTransactionMutex) asyncContext.InTransaction = false;
                _threadId = 0;
                //_startTime = 0;
                TransactionId = default;
                State         = TransactionState.None;
                throw;
            }
        }