public void ExecuteTransaction(IList <DataRequest> requests) { var request = new TransactionRequest(requests) { IsSingleStage = true, TransactionId = Guid.NewGuid() }; TransactionStatistics.ExecutedAsSingleStage(); var response = Channel.SendRequest(request); if (response is NullResponse) { return; } if (response is ExceptionResponse exResponse) { if (exResponse.ExceptionType != ExceptionType.FailedToAcquireLock) { throw new CacheException(exResponse.Message, exResponse.ExceptionType); } } TransactionStatistics.NewTransactionCompleted(); }
public void ExecuteTransaction(IList <DataRequest> requests) { // the same connector will not execute transactions in parallel lock (_transactionSync) { var status = new TransactionState(); status.Initialize(requests, CacheClients); status.CheckStatus(TransactionState.Status.Initialized); status.TryExecuteAsSingleStage(); if (status.CurrentStatus == TransactionState.Status.Completed) { TransactionStatistics.ExecutedAsSingleStage(); return; } // stage zero : send the transaction request to the servers and wait for them to acquire write locks status.AcquireLock(); status.CheckStatus(TransactionState.Status.LocksAcquired); // first stage: the durable transaction is written in the transaction log status.ProceedWithFirstStage(); // second stage: commit or rollback only the servers that processed successfully the first stage // (if a server answered with an exception response the transaction was already rolled back on this server) if (status.CurrentStatus == TransactionState.Status.FirstStageCompleted) { // commit the transaction status.CommitSecondStage(); status.CheckStatus(TransactionState.Status.SecondStageCompleted); // close the transaction status.CloseTransaction(); status.CheckStatus(TransactionState.Status.Completed); TransactionStatistics.NewTransactionCompleted(); } else { status.Rollback(); throw new CacheException( $"Error in two stage transaction. The transaction was successfully rolled back: {status.ExceptionType}", status.ExceptionType); } } }