public void Recycle(TxState state) { if (state != null) { _resuableTxState.Add(state); } }
/// <summary> /// Executes when a Stop command is sent to the service by the Service Control Manager. /// NOTE: the method is NOT triggered when the operating system shuts down, instead /// the OnShutdown() method is used! /// </summary> protected override void OnStop() { Log.Warn("{0} service stop requested...", ServiceName); if (_transferState != TxState.Stopped) { _transferState = TxState.DoNothing; // RoboCommand.Stop() is calling Process.Kill() (immediately forcing a termination // of the process, returning asynchronously), followed by Process.Dispose() // (releasing all resources used by the component). Would be nice if RoboSharp // implemented a method to check if the process has actually terminated, but // this is probably something we have to do ourselves. // TODO: this has probably improved with recent versions of RoboSharp, check it! try { _roboCommand.Stop(); } catch (Exception ex) { Log.Error("Error terminating the RoboCopy process: {0}", ex.Message); } _status.TransferInProgress = true; Log.Info("Not all files were transferred - will resume upon next start"); Log.Debug("CurrentTransferSrc: " + _status.CurrentTransferSrc); // should we delete an incompletely transferred file on the target? SendTransferInterruptedMail(); } // set the shutdown status to clean: _status.CleanShutdown = true; Log.Info("-----------------------"); Log.Info("{0} service stopped", ServiceName); Log.Info("-----------------------"); }
public void Begin(Transaction transaction) { lock (syncObject) { this.netTxState = TxState.Active; dtcControlEvent.Reset(); Tracer.Debug("Begin notification received"); if (InNetTransaction) { throw new TransactionInProgressException("A Transaction is already in Progress"); } try { Guid rmId = ResourceManagerGuid; // Enlist this object in the transaction. this.currentEnlistment = transaction.EnlistDurable(rmId, this, EnlistmentOptions.None); Tracer.Debug("Enlisted in Durable Transaction with RM Id: " + rmId); TransactionInformation txInfo = transaction.TransactionInformation; XATransactionId xaId = new XATransactionId(); this.transactionId = xaId; if (txInfo.DistributedIdentifier != Guid.Empty) { xaId.GlobalTransactionId = txInfo.DistributedIdentifier.ToByteArray(); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } else { xaId.GlobalTransactionId = Encoding.UTF8.GetBytes(txInfo.LocalIdentifier); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } // Now notify the broker that a new XA'ish transaction has started. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int)TransactionType.Begin; this.session.Connection.Oneway(info); if (Tracer.IsDebugEnabled) { Tracer.Debug("Began XA'ish Transaction:" + xaId.GlobalTransactionId.ToString()); } } catch (Exception) { dtcControlEvent.Set(); throw; } } }
public AcceptUpdateMessage(string reqId, string txId, BallotNumber ballot, TxState state) { this.ReqID = reqId; this.TxID = txId; this.Ballot = ballot; this.State = state; }
// 乐观的修改global tx state,如果version老了就重试 public async Task <TxState> SubmitGlobalTxStateOptimismAsync( string xid, TxState state) { var tryCount = 0; var maxTryTimes = 10; do { tryCount++; if (tryCount > maxTryTimes) { throw new SagaServerException("retry too many times but version expired"); } var detail = await QueryGlobalTxAsync(xid); var reply = await Client.SubmitGlobalTransactionStateAsync( new SubmitGlobalTransactionStateRequest() { Xid = xid, OldState = detail.State, State = state, OldVersion = detail.Version }); if (reply.Code == ResourceChangedErrorCode) { continue; } if (reply.Code != OkCode) { throw new SagaServerException(reply.Error); } return(reply.State); } while (true); }
internal void FreePage(long pageNumber) { if (_disposed != TxState.None) { ThrowObjectDisposed(); } try { UntrackPage(pageNumber); Debug.Assert(pageNumber >= 0); _pageLocator.Reset(pageNumber); // Remove it from the page locator. _freeSpaceHandling.FreePage(this, pageNumber); _freedPages.Add(pageNumber); if (_scratchPagesTable.TryGetValue(pageNumber, out var scratchPage)) { if (_transactionPages.Remove(scratchPage)) { _unusedScratchPages.Add(scratchPage); } _scratchPagesTable.Remove(pageNumber); } DiscardScratchModificationOn(pageNumber); } catch { _disposed |= TxState.Errored; throw; } }
/// <summary> /// Completes the async commit began previously. Must be called *within* the /// write lock, and must happen *before* the new transaction call its own commit /// method. /// </summary> public void EndAsyncCommit() { if (AsyncCommit == null) { _disposed |= TxState.Errored; ThrowInvalidAsyncEndWithoutBegin(); return;// never reached } try { AsyncCommit.Wait(); } catch (Exception e) { // an exception being thrown while / after / somewhere in the middle // of writing to the journal means that we don't know what the current // state of the journal is. We have to shut down and run recovery to // come to a known good state _disposed |= TxState.Errored; _env.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e)); throw; } if (AsyncCommit.Result) { Environment.LastWorkTime = DateTime.UtcNow; } CommitStage3_DisposeTransactionResources(); BeforeCommitFinalization?.Invoke(this); }
public void SetTxState(TxState state) { if (state == null) { return; } lock (listTxlock) { var results = transactions.Where(x => x.hash == state.hash).ToList(); if (results.Count > 0) { var oldstate = results[0]; oldstate.height = state.height; oldstate.time = state.time; oldstate.position = state.position; oldstate.size = state.size; oldstate.offset = state.offset; } else { transactions.Add(state); } } }
public async Task <TxState> SubmitBranchTxStateAsync( string xid, string branchTxId, TxState oldState, TxState state, int oldVersion, string jobId, string errorReason, byte[] sagaData) { ByteString sagaDataByteString = null; if (sagaData != null) { using (var ms = new MemoryStream(sagaData)) { sagaDataByteString = ByteString.FromStream(ms); } } var reply = await Client.SubmitBranchTransactionStateAsync( new SubmitBranchTransactionStateRequest() { Xid = xid, BranchId = branchTxId, OldState = oldState, State = state, OldVersion = oldVersion, JobId = jobId, ErrorReason = errorReason, SagaData = sagaDataByteString }); if (reply.Code != OkCode) { throw new SagaServerException(reply.Error); } return(reply.State); }
public async Task CommitAsync(Enlistment enlistment) { using (await this.syncObject.LockAsync().Await()) { try { Tracer.Debug("Commit notification received for TX id: " + this.TransactionId); if (this.TransactionId != null) { // Now notify the broker that a new XA'ish transaction has completed. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.TransactionId; info.Type = (int)TransactionType.CommitTwoPhase; await this.connection.CheckConnectedAsync().Await(); await this.connection.SyncRequestAsync(info).Await(); Tracer.Debug("Transaction Commit Done TX id: " + this.TransactionId); RecoveryLogger.LogRecovered(this.TransactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterCommit(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Commit failed with error: {1}", this.TransactionId, ex.Message); try { this.connection.OnAsyncException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } } finally { this.currentEnlistment = null; this.TransactionId = null; this.netTxState = TxState.None; CountDownLatch latch = this.recoveryComplete; if (latch != null) { latch.countDown(); } this.dtcControlEvent.Set(); } } }
public RefundResponseMessage(string oid, string pid, Refund refund, TxState state, string msg, ResponseReasonCode reason) : base(Methods.REFUND_RESPONSE) { this.orderId = oid; this.paymentId = pid; this.refund = refund; this.code = state; this.message = msg; this.reason = reason; }
public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) { lock (this.syncObject) { try { Tracer.Debug("Single Phase Commit notification received for TX id: " + this.transactionId); if (this.transactionId != null) { BeforeEnd(); // Now notify the broker that a new XA'ish transaction has completed. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int)TransactionType.CommitOnePhase; this.connection.CheckConnected(); this.connection.SyncRequest(info); Tracer.Debug("Transaction Single Phase Commit Done TX id: " + this.transactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterCommit(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Single Phase Commit failed with error: {1}", this.transactionId, ex.Message); AfterRollback(); enlistment.Done(); try { this.connection.OnException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } } finally { this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; this.dtcControlEvent.Set(); } } }
/// <summary> /// This begins an async commit and starts a new transaction immediately. /// The current transaction is considered completed in memory but not yet /// committed to disk. This *must* be completed by calling EndAsyncCommit. /// </summary> public LowLevelTransaction BeginAsyncCommitAndStartNewTransaction() { if (Flags != TransactionFlags.ReadWrite) { ThrowReadTranscationCannotDoAsyncCommit(); } if (_asyncCommitNextTransaction != null) { ThrowAsyncCommitAlreadyCalled(); } // we have to check the state before we complete the transaction // because that would change whether we need to write to the journal var writeToJournalIsRequired = WriteToJournalIsRequired(); CommitStage1_CompleteTransaction(); var nextTx = new LowLevelTransaction(this, writeToJournalIsRequired ? Id + 1 : Id ); _asyncCommitNextTransaction = nextTx; AsyncCommit = writeToJournalIsRequired ? Task.Run(() => { CommitStage2_WriteToJournal(); return(true); }) : NoWriteToJournalRequiredTask; try { _env.IncrementUsageOnNewTransaction(); _env.ActiveTransactions.Add(nextTx); _env.WriteTransactionStarted(); return(nextTx); } catch (Exception) { // failure here means that we'll try to complete the current transaction normaly // then throw as if commit was called normally and the next transaction failed _env.DecrementUsageOnTransactionCreationFailure(); EndAsyncCommit(); AsyncCommit = null; _disposed |= TxState.Errored; throw; } }
public async Task InDoubtAsync(Enlistment enlistment) { using (await syncObject.LockAsync().Await()) { try { Tracer.Debug("In Doubt notification received for TX id: " + this.TransactionId); await BeforeEndAsync().Await(); // Now notify the broker that Rollback should be performed. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.TransactionId; info.Type = (int)TransactionType.End; await this.connection.CheckConnectedAsync().Await(); await this.connection.SyncRequestAsync((TransactionInfo)info.Clone()).Await(); info.Type = (int)TransactionType.Rollback; await this.connection.CheckConnectedAsync().Await(); await this.connection.SyncRequestAsync(info).Await(); Tracer.Debug("InDoubt Transaction Rollback Done TX id: " + this.TransactionId); RecoveryLogger.LogRecovered(this.TransactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterRollback(); } finally { this.currentEnlistment = null; this.TransactionId = null; this.netTxState = TxState.None; CountDownLatch latch = this.recoveryComplete; if (latch != null) { latch.countDown(); } this.dtcControlEvent.Set(); } } }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private org.neo4j.kernel.impl.api.TransactionToApply createNodeAndProperty(int progress) throws Exception internal virtual TransactionToApply CreateNodeAndProperty(int progress) { TransactionState txState = new TxState(); long nodeId = NodeIds.nextId(); txState.NodeDoCreate(nodeId); txState.NodeDoAddLabel(outerInstance.descriptor.LabelId, nodeId); txState.NodeDoAddProperty(nodeId, outerInstance.descriptor.PropertyId, PropertyValue(Id, progress)); ICollection <StorageCommand> commands = new List <StorageCommand>(); using (StorageReader statement = StorageEngine.newReader()) { StorageEngine.createCommands(commands, txState, statement, null, 0, NO_DECORATION); } return(Tx(commands)); }
private void prepareToTransmitFlags(int seconds) { if (tx_state != TxState.IDLE) { if (ConsoleOut) { Console.WriteLine("Warning: trying to trasmit while Afsk1200 modulator is busy, discarding"); } return; } ; tx_bytes = null; // no data tx_state = TxState.PREAMBLE; tx_index = (int)Math.Ceiling((double)seconds / (8.0 / 1200.0)); // number of flags to transmit tx_symbol_phase = tx_dds_phase = 0.0f; }
private TxState GetTxState() { TxState state; if (!_resuableTxState.TryTake(out state)) { state = new TxState(); state.ReadContext = new ReadContext(); int capacity = PartitionSize + RESERVED_PARTITION_COUNT; state.Partitions = new List <IPartition>(capacity); state.Locks = new List <bool>(); state.PartitionDataStorage = new PartitionTxData[capacity]; } return(state); }
public void Dispose() { if (_disposed.HasFlag(TxState.Disposed)) { return; } try { if (!Committed && !RolledBack && Flags == TransactionFlags.ReadWrite) { Rollback(); } _disposed |= TxState.Disposed; PersistentContext.FreePageLocator(_pageLocator); } finally { _env.TransactionCompleted(this); foreach (var pagerState in _pagerStates) { pagerState.Release(); } if (JournalFiles != null) { foreach (var journalFile in JournalFiles) { journalFile.Release(); } } _root?.Dispose(); _freeSpaceTree?.Dispose(); _allocator.AllocationFailed -= MarkTransactionAsFailed; if (_disposeAllocator) { _allocator.Dispose(); } OnDispose?.Invoke(this); } }
private void StoreTxState(uint blocktime, uint height, DecodeRawTransactionResponse txraw, RawTransactionResponse tx, uint index, long offset, uint rawsize) { var time = blocktime < PeercoinConstants.ProtocolV10SwitchTime && txraw.time.HasValue ? (uint)txraw.time.Value : blocktime; var state = new TxState { hash = txraw.txid, height = height, offset = (uint)offset, position = index, size = rawsize, time = time }; transactionRepository.SetTxState(state); }
public async Task <TxState> SubmitGlobalTxStateAsync( string xid, TxState oldState, TxState state, int oldVersion) { var reply = await Client.SubmitGlobalTransactionStateAsync( new SubmitGlobalTransactionStateRequest() { Xid = xid, OldState = oldState, State = state, OldVersion = oldVersion }); if (reply.Code != OkCode) { throw new SagaServerException(reply.Error); } return(reply.State); }
public static string GetStateString(TxState state) { if (state == TxState.Confirmed) { return(TextTools.RetrieveStringFromResource("Confirmed")); } else if (state == TxState.Awaiting) { return(TextTools.RetrieveStringFromResource("Awaiting")); } else if (state == TxState.Unconfirmed) { return(TextTools.RetrieveStringFromResource("Unconfirmed")); } else { return("NA"); } }
private void prepareToTransmit(Packet p) { if (tx_state != TxState.IDLE) { if (ConsoleOut) { Console.WriteLine("Warning: trying to trasmit while Afsk1200 modulator is busy, discarding"); } return; } ; tx_bytes = p.bytesWithCRC(); // This includes the CRC tx_state = TxState.PREAMBLE; tx_index = (int)Math.Ceiling(tx_delay * 0.01 / (8.0 / 1200.0)); // number of flags to transmit if (tx_index < 1) { tx_index = 1; } tx_symbol_phase = tx_dds_phase = 0.0f; }
private sbyte[] CreateCommands(string tokenName) { StorageEngine storageEngine = _storageEngineSupplier.get(); ICollection <StorageCommand> commands = new List <StorageCommand>(); TransactionState txState = new TxState(); int tokenId = Math.toIntExact(_idGeneratorFactory.get(_tokenIdType).nextId()); _tokenCreator.createToken(txState, tokenName, tokenId); try { using (StorageReader statement = storageEngine.NewReader()) { storageEngine.CreateCommands(commands, txState, statement, [email protected]_Fields.None, long.MaxValue, NO_DECORATION); } } catch (Exception e) when(e is CreateConstraintFailureException || e is TransactionFailureException || e is ConstraintValidationException) { throw new Exception("Unable to create token '" + tokenName + "'", e); } return(ReplicatedTokenRequestSerializer.CommandBytes(commands)); }
private void CommitStage2_WriteToJournal() { // In the case of non-lazy transactions, we must flush the data from older lazy transactions // to ensure the sequentiality of the data. Stopwatch sp = null; if (_requestedCommitStats != null) { sp = Stopwatch.StartNew(); } string journalFilePath; CompressedPagesResult numberOfWrittenPages; try { numberOfWrittenPages = _journal.WriteToJournal(this, out journalFilePath); FlushedToJournal = true; _updatePageTranslationTableAndUnusedPages = numberOfWrittenPages.UpdatePageTranslationTableAndUnusedPages; if (SimulateThrowingOnCommitStage2) { ThrowSimulateErrorOnCommitStage2(); } } catch { _disposed |= TxState.Errored; throw; } if (_requestedCommitStats != null) { _requestedCommitStats.WriteToJournalDuration = sp.Elapsed; _requestedCommitStats.NumberOfModifiedPages = numberOfWrittenPages.NumberOfUncompressedPages; _requestedCommitStats.NumberOf4KbsWrittenToDisk = numberOfWrittenPages.NumberOf4Kbs; _requestedCommitStats.JournalFilePath = journalFilePath; } }
private void CommitStage3_DisposeTransactionResources() { // an exception being thrown after the transaction has been committed to disk // will corrupt the in memory state, and require us to restart (and recover) to // be in a valid state try { ValidateAllPages(); Allocator.Release(ref _txHeaderMemory); Committed = true; _updatePageTranslationTableAndUnusedPages?.ExecuteAfterCommit(); _env.TransactionAfterCommit(this); if (_asyncCommitNextTransaction != null) { var old = _asyncCommitNextTransaction.JournalFiles; _asyncCommitNextTransaction.JournalFiles = _env.Journal.Files; foreach (var journalFile in _asyncCommitNextTransaction.JournalFiles) { journalFile.AddRef(); } foreach (var journalFile in old) { journalFile.Release(); } } } catch (Exception e) { _disposed |= TxState.Errored; _env.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e)); throw; } }
public void Prepare(PreparingEnlistment preparingEnlistment) { lock (this.syncObject) { this.netTxState = TxState.Pending; try { Tracer.Debug("Prepare notification received for TX id: " + this.transactionId); BeforeEnd(); // Before sending the request to the broker, log the recovery bits, if // this fails we can't prepare and the TX should be rolled back. RecoveryLogger.LogRecoveryInfo(this.transactionId as XATransactionId, preparingEnlistment.RecoveryInformation()); // Inform the broker that work on the XA'sh TX Branch is complete. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int) TransactionType.End; this.connection.CheckConnected(); this.connection.SyncRequest(info); // Prepare the Transaction for commit. info.Type = (int) TransactionType.Prepare; IntegerResponse response = (IntegerResponse) this.connection.SyncRequest(info); if (response.Result == XA_READONLY) { Tracer.Debug("Transaction Prepare done and doesn't need a commit, TX id: " + this.transactionId); this.transactionId = null; this.currentEnlistment = null; // Read Only means there's nothing to recover because there was no // change on the broker. RecoveryLogger.LogRecovered(this.transactionId as XATransactionId); // if server responds that nothing needs to be done, then reply prepared // but clear the current state data so we appear done to the commit method. preparingEnlistment.Prepared(); // Done so commit won't be called. AfterCommit(); // A Read-Only TX is considered closed at this point, DTC won't call us again. this.dtcControlEvent.Set(); } else { Tracer.Debug("Transaction Prepare succeeded TX id: " + this.transactionId); // If work finished correctly, reply prepared preparingEnlistment.Prepared(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Prepare failed with error: {1}", this.transactionId, ex.Message); AfterRollback(); preparingEnlistment.ForceRollback(); try { this.connection.OnException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; this.dtcControlEvent.Set(); } } }
public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) { lock (this.syncObject) { try { Tracer.Debug("Single Phase Commit notification received for TX id: " + this.transactionId); if (this.transactionId != null) { BeforeEnd(); // Now notify the broker that a new XA'ish transaction has completed. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int) TransactionType.CommitOnePhase; this.connection.CheckConnected(); this.connection.SyncRequest(info); Tracer.Debug("Transaction Single Phase Commit Done TX id: " + this.transactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterCommit(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Single Phase Commit failed with error: {1}", this.transactionId, ex.Message); AfterRollback(); enlistment.Done(); try { this.connection.OnException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } } finally { this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; this.dtcControlEvent.Set(); } } }
public void Rollback(Enlistment enlistment) { lock (this.syncObject) { try { Tracer.Debug("Rollback notification received for TX id: " + this.transactionId); if (this.transactionId != null) { BeforeEnd(); // Now notify the broker that a new XA'ish transaction has started. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int) TransactionType.End; this.connection.CheckConnected(); this.connection.SyncRequest(info); info.Type = (int) TransactionType.Rollback; this.connection.CheckConnected(); this.connection.SyncRequest(info); Tracer.Debug("Transaction Rollback Done TX id: " + this.transactionId); RecoveryLogger.LogRecovered(this.transactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterRollback(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Rollback failed with error: {1}", this.transactionId, ex.Message); AfterRollback(); try { this.connection.OnException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } } finally { this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; CountDownLatch latch = this.recoveryComplete; if (latch != null) { latch.countDown(); } this.dtcControlEvent.Set(); } } }
public async Task PrepareAsync(PreparingEnlistment preparingEnlistment) { using (await this.syncObject.LockAsync().Await()) { this.netTxState = TxState.Pending; try { Tracer.Debug("Prepare notification received for TX id: " + this.TransactionId); await BeforeEndAsync().Await(); // Before sending the request to the broker, log the recovery bits, if // this fails we can't prepare and the TX should be rolled back. RecoveryLogger.LogRecoveryInfo(this.TransactionId as XATransactionId, preparingEnlistment.RecoveryInformation()); // Inform the broker that work on the XA'sh TX Branch is complete. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.TransactionId; info.Type = (int)TransactionType.End; await this.connection.CheckConnectedAsync().Await(); await this.connection.SyncRequestAsync((TransactionInfo)info.Clone()).Await(); // Prepare the Transaction for commit. info.Type = (int)TransactionType.Prepare; IntegerResponse response = (IntegerResponse)await this.connection.SyncRequestAsync(info).Await(); if (response.Result == XA_READONLY) { Tracer.Debug("Transaction Prepare done and doesn't need a commit, TX id: " + this.TransactionId); this.TransactionId = null; this.currentEnlistment = null; // Read Only means there's nothing to recover because there was no // change on the broker. RecoveryLogger.LogRecovered(this.TransactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. // otherwise the DTC will call Commit or Rollback but another transaction // can already be in progress and this one would be commited or rolled back // immediately. preparingEnlistment.Done(); // Done so commit won't be called. AfterCommit(); // A Read-Only TX is considered closed at this point, DTC won't call us again. this.dtcControlEvent.Set(); } else { Tracer.Debug("Transaction Prepare succeeded TX id: " + this.TransactionId); // If work finished correctly, reply prepared preparingEnlistment.Prepared(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Prepare failed with error: {1}", this.TransactionId, ex.Message); AfterRollback(); preparingEnlistment.ForceRollback(); try { this.connection.OnAsyncException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } this.currentEnlistment = null; this.TransactionId = null; this.netTxState = TxState.None; this.dtcControlEvent.Set(); } } }
public void Begin(Transaction transaction) { using (syncObject.Lock()) { dtcControlEvent.Reset(); Tracer.Debug("Begin notification received"); if (InNetTransaction) { throw new TransactionInProgressException("A Transaction is already in Progress"); } try { Guid rmId = ResourceManagerGuid; // Enlist this object in the transaction. this.currentEnlistment = transaction.EnlistDurable(rmId, this, EnlistmentOptions.None); // In case of a exception in the current method the transaction will be rolled back. // Until Begin Transaction is completed we consider to be in a rollback scenario. this.netTxState = TxState.Pending; Tracer.Debug("Enlisted in Durable Transaction with RM Id: " + rmId); TransactionInformation txInfo = transaction.TransactionInformation; XATransactionId xaId = new XATransactionId(); this.TransactionId = xaId; if (txInfo.DistributedIdentifier != Guid.Empty) { xaId.GlobalTransactionId = txInfo.DistributedIdentifier.ToByteArray(); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } else { xaId.GlobalTransactionId = Encoding.UTF8.GetBytes(txInfo.LocalIdentifier); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } // Now notify the broker that a new XA'ish transaction has started. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.TransactionId; info.Type = (int)TransactionType.Begin; this.session.Connection.Oneway(info); // Begin Transaction is completed successfully. Change to transaction active state now. this.netTxState = TxState.Active; SignalTransactionStarted(); if (Tracer.IsDebugEnabled) { Tracer.Debug("Began XA'ish Transaction:" + xaId); } } catch (Exception) { // When in pending state the rollback will signal that a new transaction can be started. Otherwise do it here. if (netTxState != TxState.Pending) { netTxState = TxState.None; dtcControlEvent.Set(); } throw; } } }
private async Task UpdateState(ISet <string> acceptors, string txId, BallotNumber ballot, TxState state, int timeoutMs) { var reqId = Guid.NewGuid().ToString(); var localMutex = new object(); var isAccepted = false; var acks = new HashSet <string>(); var accepted = new TaskCompletionSource <bool>(); foreach (var acceptorId in acceptors) { this.bus.AcceptUpdate(acceptorId, new AcceptUpdateMessage(reqId, txId, ballot, state)); } var handler1 = this.bus.WaitForUpdateAccepted(reqId, (acceptorId) => { lock (localMutex) { if (isAccepted) { return(WaitStrategy.StopWaiting); } acks.Add(acceptorId); if (acks.Count >= 1 + acceptors.Count / 2) { isAccepted = true; accepted.SetResult(true); return(WaitStrategy.StopWaiting); } return(WaitStrategy.KeepWaiting); } }); this.timer.SetTimeout(() => { lock (localMutex) { if (isAccepted) { return; } accepted.SetException(new TimeoutException()); handler1.Dispose(); } }, timeoutMs); _ = await accepted.Task; }
public void Rollback(Enlistment enlistment) { lock (this.syncObject) { try { Tracer.Debug("Rollback notification received for TX id: " + this.transactionId); if (this.transactionId != null) { BeforeEnd(); // Now notify the broker that a new XA'ish transaction has started. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int)TransactionType.End; this.connection.CheckConnected(); this.connection.SyncRequest(info); info.Type = (int)TransactionType.Rollback; this.connection.CheckConnected(); this.connection.SyncRequest(info); Tracer.Debug("Transaction Rollback Done TX id: " + this.transactionId); RecoveryLogger.LogRecovered(this.transactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterRollback(); } } catch (Exception ex) { Tracer.DebugFormat("Transaction[{0}] Rollback failed with error: {1}", this.transactionId, ex.Message); AfterRollback(); try { this.connection.OnException(ex); } catch (Exception error) { Tracer.Error(error.ToString()); } } finally { this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; CountDownLatch latch = this.recoveryComplete; if (latch != null) { latch.countDown(); } this.dtcControlEvent.Set(); } } }
public TxStateMessage(TxState txState) : base(Methods.TX_STATE) { this.txState = txState; }
public void Begin(Transaction transaction) { lock (syncObject) { this.netTxState = TxState.Active; dtcControlEvent.Reset(); Tracer.Debug("Begin notification received"); if (InNetTransaction) { throw new TransactionInProgressException("A Transaction is already in Progress"); } try { Guid rmId = ResourceManagerGuid; // Enlist this object in the transaction. this.currentEnlistment = transaction.EnlistDurable(rmId, this, EnlistmentOptions.None); Tracer.Debug("Enlisted in Durable Transaction with RM Id: " + rmId); TransactionInformation txInfo = transaction.TransactionInformation; XATransactionId xaId = new XATransactionId(); this.transactionId = xaId; if (txInfo.DistributedIdentifier != Guid.Empty) { xaId.GlobalTransactionId = txInfo.DistributedIdentifier.ToByteArray(); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } else { xaId.GlobalTransactionId = Encoding.UTF8.GetBytes(txInfo.LocalIdentifier); xaId.BranchQualifier = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); } // Now notify the broker that a new XA'ish transaction has started. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int) TransactionType.Begin; this.session.Connection.Oneway(info); if (Tracer.IsDebugEnabled) { Tracer.Debug("Began XA'ish Transaction:" + xaId.GlobalTransactionId.ToString()); } } catch (Exception) { dtcControlEvent.Set(); throw; } } }
public void InDoubt(Enlistment enlistment) { lock (syncObject) { try { Tracer.Debug("In Doubt notification received for TX id: " + this.transactionId); BeforeEnd(); // Now notify the broker that Rollback should be performed. TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.connection.ConnectionId; info.TransactionId = this.transactionId; info.Type = (int) TransactionType.End; this.connection.CheckConnected(); this.connection.SyncRequest(info); info.Type = (int) TransactionType.Rollback; this.connection.CheckConnected(); this.connection.SyncRequest(info); Tracer.Debug("InDoubt Transaction Rollback Done TX id: " + this.transactionId); RecoveryLogger.LogRecovered(this.transactionId as XATransactionId); // if server responds that nothing needs to be done, then reply done. enlistment.Done(); AfterRollback(); } finally { this.currentEnlistment = null; this.transactionId = null; this.netTxState = TxState.None; CountDownLatch latch = this.recoveryComplete; if (latch != null) { latch.countDown(); } this.dtcControlEvent.Set(); } } }
public PromiseAcceptedMessage(BallotNumber prevBallot, TxState state) { this.PrevBallot = prevBallot; this.State = state; }