public virtual Response processForgetTransaction(TransactionInfo info) { return null; }
public virtual Response processBeginTransaction(TransactionInfo info) { return null; }
public virtual Response processCommitTransactionTwoPhase(TransactionInfo info) { return null; }
public virtual Response processRecoverTransactions(TransactionInfo info) { return null; }
public virtual Response processRollbackTransaction(TransactionInfo info) { return null; }
public override Response processRollbackTransaction(TransactionInfo info) { if(TrackTransactions && info != null) { ConnectionId connectionId = info.ConnectionId; if(connectionId != null) { ConnectionState cs = connectionStates[connectionId]; if(cs != null) { TransactionState transactionState = cs[info.TransactionId]; if(transactionState != null) { transactionState.addCommand(info); return new Tracked(new RemoveTransactionAction(info, this)); } } } } return null; }
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 Begin() { if(!InTransaction) { this.transactionId = this.session.Connection.CreateLocalTransactionId(); TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.session.Connection.ConnectionId; info.TransactionId = transactionId; info.Type = (int) TransactionType.Begin; this.session.Connection.Oneway(info); if(Tracer.IsDebugEnabled) { Tracer.Debug("Begin:" + this.transactionId.ToString()); } } }
public override Response processCommitTransactionOnePhase(TransactionInfo info) { if(TrackTransactions && info != null) { ConnectionId connectionId = info.ConnectionId; if(connectionId != null) { ConnectionState cs = null; if(connectionStates.TryGetValue(connectionId, out cs)) { TransactionState transactionState = cs[info.TransactionId]; if(transactionState != null) { transactionState.addCommand(info); return new Tracked(new RemoveTransactionAction(info, this)); } } } } return null; }
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(); } } }
private XATransactionId[] TryRecoverBrokerTXIds() { Tracer.Debug("Checking for Recoverable Transactions on Broker."); TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.session.Connection.ConnectionId; info.Type = (int)TransactionType.Recover; this.connection.CheckConnected(); DataArrayResponse response = this.connection.SyncRequest(info) as DataArrayResponse; if (response != null && response.Data.Length > 0) { Tracer.DebugFormat("Broker reports there are {0} recoverable XA Transactions", response.Data.Length); List<XATransactionId> recovered = new List<XATransactionId>(); foreach (DataStructure ds in response.Data) { XATransactionId xid = ds as XATransactionId; if (xid != null) { recovered.Add(xid); } } return recovered.ToArray(); } return new XATransactionId[0]; }
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 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 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 override Response processBeginTransaction(TransactionInfo info) { if(TrackTransactions && info != null && info.TransactionId != null) { ConnectionId connectionId = info.ConnectionId; if(connectionId != null) { ConnectionState cs = connectionStates[connectionId]; if(cs != null) { cs.addTransactionState(info.TransactionId); TransactionState state = cs[info.TransactionId]; state.addCommand(info); } } return TRACKED_RESPONSE_MARKER; } return null; }
public override Response processEndTransaction(TransactionInfo info) { if(TrackTransactions && info != null) { ConnectionId connectionId = info.ConnectionId; if(connectionId != null) { ConnectionState cs = null; if(connectionStates.TryGetValue(connectionId, out cs)) { TransactionState transactionState = cs[info.TransactionId]; if(transactionState != null) { transactionState.addCommand(info); } } } return TRACKED_RESPONSE_MARKER; } return null; }
public override Response processPrepareTransaction(TransactionInfo info) { if(TrackTransactions && info != null) { ConnectionId connectionId = info.ConnectionId; if(connectionId != null) { ConnectionState cs = connectionStates[connectionId]; if(cs != null) { TransactionState transactionState = cs[info.TransactionId]; if(transactionState != null) { transactionState.addCommand(info); } } } return TRACKED_RESPONSE_MARKER; } return null; }
public virtual Response processPrepareTransaction(TransactionInfo info) { return null; }
public RemoveTransactionAction(TransactionInfo info, ConnectionStateTracker aCst) { this.info = info; this.cst = aCst; }
public void Commit() { if(InTransaction) { this.BeforeEnd(); if(Tracer.IsDebugEnabled) { Tracer.Debug("Commit: " + this.transactionId + " syncCount: " + (synchronizations != null ? synchronizations.Count : 0)); } TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.session.Connection.ConnectionId; info.TransactionId = transactionId; info.Type = (int) TransactionType.CommitOnePhase; this.transactionId = null; this.session.Connection.SyncRequest(info); this.AfterCommit(); } }