public void TestPurgeTransactionRecord() { RecoveryFileLogger logger = new RecoveryFileLogger(); byte[] globalId = new byte[32]; byte[] branchQ = new byte[32]; byte[] recoveryData = new byte[256]; Random gen = new Random(); gen.NextBytes(globalId); gen.NextBytes(branchQ); gen.NextBytes(recoveryData); logger.Location = nonDefaultLogLocation; logger.Initialize(rmId.ToString()); XATransactionId xid = new XATransactionId(); xid.GlobalTransactionId = globalId; xid.BranchQualifier = branchQ; logger.LogRecoveryInfo(xid, recoveryData); Assert.IsTrue(File.Exists(logger.Location + Path.DirectorySeparatorChar + rmId.ToString() + ".bin"), "Recovery File was not created"); logger.Purge(); Assert.IsFalse(File.Exists(logger.Location + Path.DirectorySeparatorChar + rmId.ToString() + ".bin"), "Recovery File was not created"); }
public void LogRecoveryInfo(XATransactionId xid, byte[] recoveryInformation) { if (recoveryInformation == null || recoveryInformation.Length == 0) { return; } try { lock (syncRoot) { RecoveryInformation info = new RecoveryInformation(xid, recoveryInformation); Tracer.Debug("Serializing Recovery Info to file: " + Filename); IFormatter formatter = new BinaryFormatter(); using (FileStream recoveryLog = new FileStream(Filename, FileMode.OpenOrCreate, FileAccess.Write)) { formatter.Serialize(recoveryLog, info); } } } catch (Exception ex) { Tracer.Error("Error while storing TX Recovery Info, message: " + ex.Message); throw; } }
private async Task <XATransactionId[]> TryRecoverBrokerTXIdsAsync() { Tracer.Debug("Checking for Recoverable Transactions on Broker."); TransactionInfo info = new TransactionInfo(); info.ConnectionId = this.session.Connection.ConnectionId; info.Type = (int)TransactionType.Recover; await this.connection.CheckConnectedAsync().Await(); DataArrayResponse response = await this.connection.SyncRequestAsync(info).Await() 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 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 TestLogTransactionRecord() { RecoveryFileLogger logger = new RecoveryFileLogger(); byte[] globalId = new byte[32]; byte[] branchQ = new byte[32]; byte[] recoveryData = new byte[256]; Random gen = new Random(); gen.NextBytes(globalId); gen.NextBytes(branchQ); gen.NextBytes(recoveryData); logger.Location = nonDefaultLogLocation; logger.Initialize(rmId); XATransactionId xid = new XATransactionId(); xid.GlobalTransactionId = globalId; xid.BranchQualifier = branchQ; logger.LogRecoveryInfo(xid, recoveryData); Assert.IsTrue(File.Exists(Path.Combine(logger.Location, rmId + ".bin")), "Recovery File was not created"); }
private string CreateFilename(XATransactionId xaTransactionId) { return(string.Format( "{0}{1}{2}_{3}.bin", this.Location, Path.DirectorySeparatorChar, this.ResourceManagerId, GetHexValue(xaTransactionId))); }
// // Un-marshal an object instance from the data input stream // public override void TightUnmarshal(OpenWireFormat wireFormat, Object o, BinaryReader dataIn, BooleanStream bs) { base.TightUnmarshal(wireFormat, o, dataIn, bs); XATransactionId info = (XATransactionId)o; info.FormatId = dataIn.ReadInt32(); info.GlobalTransactionId = ReadBytes(dataIn, bs.ReadBoolean()); info.BranchQualifier = ReadBytes(dataIn, bs.ReadBoolean()); }
public TransactionData() { Random.NextBytes(this.globalId); Random.NextBytes(this.branchQ); Random.NextBytes(this.recoveryData); this.xid = new XATransactionId(); this.xid.GlobalTransactionId = this.globalId; this.xid.BranchQualifier = this.branchQ; }
// // Write the booleans that this object uses to a BooleanStream // public override int TightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs) { XATransactionId info = (XATransactionId)o; int rc = base.TightMarshal1(wireFormat, info, bs); bs.WriteBoolean(info.GlobalTransactionId != null); rc += info.GlobalTransactionId == null ? 0 : info.GlobalTransactionId.Length + 4; bs.WriteBoolean(info.BranchQualifier != null); rc += info.BranchQualifier == null ? 0 : info.BranchQualifier.Length + 4; return(rc + 4); }
/// <summary> /// Converts the given transaction ID into a String /// </summary> public static String ToString(TransactionId txnId) { if (txnId is LocalTransactionId) { LocalTransactionId ltxnId = (LocalTransactionId)txnId; return("" + ltxnId.Value); } else if (txnId is XATransactionId) { XATransactionId xaTxnId = (XATransactionId)txnId; return("XID:" + xaTxnId.FormatId + ":" + ToHexFromBytes(xaTxnId.GlobalTransactionId) + ":" + ToHexFromBytes(xaTxnId.BranchQualifier)); } return(null); }
public void LogRecovered(XATransactionId xid) { if (this.PreLogRecoverdEvent != null) { this.PreLogRecoverdEvent(xid); } this.containedLogger.LogRecovered(xid); if (this.PostLogRecoverdEvent != null) { this.PostLogRecoverdEvent(xid); } }
public void LogRecovered(XATransactionId xid) { try { string filename = this.CreateFilename(xid); Tracer.Debug("Attempting to remove stale Recovery Info file: " + filename); File.Delete(filename); } catch (Exception ex) { Tracer.Debug("Caught Exception while removing stale RecoveryInfo file: " + ex.Message); } }
public void LogRecovered(XATransactionId xid) { lock (syncRoot) { try { Tracer.Debug("Attempting to remove stale Recovery Info file: " + Filename); File.Delete(Filename); } catch (Exception ex) { Tracer.Debug("Caught Exception while removing stale RecoveryInfo file: " + ex.Message); return; } } }
public virtual bool Equals(XATransactionId that) { if(!Equals(this.FormatId, that.FormatId)) { return false; } if(!ArrayEquals(this.GlobalTransactionId, that.GlobalTransactionId)) { return false; } if(!ArrayEquals(this.BranchQualifier, that.BranchQualifier)) { return false; } return true; }
public virtual bool Equals(XATransactionId that) { if (!Equals(this.FormatId, that.FormatId)) { return(false); } if (!Equals(this.GlobalTransactionId, that.GlobalTransactionId)) { return(false); } if (!Equals(this.BranchQualifier, that.BranchQualifier)) { return(false); } return(true); }
// // Write a object instance to data output stream // public override void TightMarshal2(OpenWireFormat wireFormat, Object o, BinaryWriter dataOut, BooleanStream bs) { base.TightMarshal2(wireFormat, o, dataOut, bs); XATransactionId info = (XATransactionId)o; dataOut.Write(info.FormatId); if (bs.ReadBoolean()) { dataOut.Write(info.GlobalTransactionId.Length); dataOut.Write(info.GlobalTransactionId); } if (bs.ReadBoolean()) { dataOut.Write(info.BranchQualifier.Length); dataOut.Write(info.BranchQualifier); } }
// // Write a object instance to data output stream // public override void LooseMarshal(OpenWireFormat wireFormat, Object o, BinaryWriter dataOut) { XATransactionId info = (XATransactionId)o; base.LooseMarshal(wireFormat, o, dataOut); dataOut.Write(info.FormatId); dataOut.Write(info.GlobalTransactionId != null); if (info.GlobalTransactionId != null) { dataOut.Write(info.GlobalTransactionId.Length); dataOut.Write(info.GlobalTransactionId); } dataOut.Write(info.BranchQualifier != null); if (info.BranchQualifier != null) { dataOut.Write(info.BranchQualifier.Length); dataOut.Write(info.BranchQualifier); } }
public void LogRecoveryInfo(XATransactionId xid, byte[] recoveryInformation) { if (recoveryInformation == null || recoveryInformation.Length == 0) { return; } if (this.PreLogRecoveryInfoEvent != null) { this.PreLogRecoveryInfoEvent(xid, recoveryInformation); } this.containedLogger.LogRecoveryInfo(xid, recoveryInformation); if (this.PostLogRecoveryInfoEvent != null) { this.PostLogRecoveryInfoEvent(xid, recoveryInformation); } }
public void TestRecoverLoggedRecord() { RecoveryFileLogger logger = new RecoveryFileLogger(); byte[] globalId = new byte[32]; byte[] branchQ = new byte[32]; byte[] recoveryData = new byte[256]; Random gen = new Random(); gen.NextBytes(globalId); gen.NextBytes(branchQ); gen.NextBytes(recoveryData); logger.Location = nonDefaultLogLocation; logger.Initialize(rmId.ToString()); XATransactionId xid = new XATransactionId(); xid.GlobalTransactionId = globalId; xid.BranchQualifier = branchQ; logger.LogRecoveryInfo(xid, recoveryData); Assert.IsTrue(File.Exists(logger.Location + Path.DirectorySeparatorChar + rmId.ToString() + ".bin"), "Recovery File was not created"); Assert.IsTrue(logger.GetRecoverables().Length == 1, "Did not recover the logged record."); KeyValuePair <XATransactionId, byte[]>[] records = logger.GetRecoverables(); Assert.AreEqual(1, records.Length); Assert.AreEqual(globalId, records[0].Key.GlobalTransactionId, "Incorrect Global TX Id returned"); Assert.AreEqual(branchQ, records[0].Key.BranchQualifier, "Incorrect Branch Qualifier returned"); Assert.AreEqual(recoveryData, records[0].Value, "Incorrect Recovery Information returned"); }
public RecoveryInformation(XATransactionId xaId, byte[] recoveryInfo) { this.Xid = xaId; this.txRecoveryInfo = recoveryInfo; }
private static string GetHexValue(XATransactionId xid) { string transactionIdHexValue = BitConverter.ToString(xid.GlobalTransactionId); return(transactionIdHexValue.Replace("-", string.Empty)); }
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; } } }
public void FailOnPreLogRecoveryHook(XATransactionId xid, byte[] recoveryInformatio) { Tracer.Debug("Throwing Error before the Recovery Information is Logged."); throw new Exception("Intentional Error Logging Recovery Information"); }
public void Begin(Transaction transaction) { Tracer.Debug("Begin notification received"); if(InNetTransaction) { throw new TransactionInProgressException("A Transaction is already in Progress"); } 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()); } }