コード例 #1
0
        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");
        }
コード例 #2
0
        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;
            }
        }
コード例 #3
0
        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]);
        }
コード例 #4
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;
                }
            }
        }
コード例 #5
0
        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");
        }
コード例 #6
0
 private string CreateFilename(XATransactionId xaTransactionId)
 {
     return(string.Format(
                "{0}{1}{2}_{3}.bin",
                this.Location,
                Path.DirectorySeparatorChar,
                this.ResourceManagerId,
                GetHexValue(xaTransactionId)));
 }
コード例 #7
0
        //
        // 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());
        }
コード例 #8
0
            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;
            }
コード例 #9
0
        //
        // 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);
        }
コード例 #10
0
 /// <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);
 }
コード例 #11
0
        public void LogRecovered(XATransactionId xid)
        {
            if (this.PreLogRecoverdEvent != null)
            {
                this.PreLogRecoverdEvent(xid);
            }

            this.containedLogger.LogRecovered(xid);

            if (this.PostLogRecoverdEvent != null)
            {
                this.PostLogRecoverdEvent(xid);
            }
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
0
 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;
         }
     }
 }
コード例 #14
0
        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;
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        //
        // 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);
            }
        }
コード例 #17
0
        //
        // 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);
            }
        }
コード例 #18
0
        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);
            }
        }
コード例 #19
0
        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");
        }
コード例 #20
0
 public RecoveryInformation(XATransactionId xaId, byte[] recoveryInfo)
 {
     this.Xid            = xaId;
     this.txRecoveryInfo = recoveryInfo;
 }
コード例 #21
0
        private static string GetHexValue(XATransactionId xid)
        {
            string transactionIdHexValue = BitConverter.ToString(xid.GlobalTransactionId);

            return(transactionIdHexValue.Replace("-", string.Empty));
        }
コード例 #22
0
        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;
                }
            }
        }
コード例 #23
0
 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");
 }
コード例 #24
0
        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());
            }
        }