Ejemplo n.º 1
0
        /// <summary>
        /// Returns the orphaned transaction <see cref="Guid" />s discovered after
        /// <see cref="Open" /> returns <see cref="LogStatus.Recover" />.
        /// </summary>
        /// <returns>The list of transaction <see cref="Guid" />s.</returns>
        /// <exception cref="TransactionException">Thrown if the log is not open.</exception>
        /// <remarks>
        /// This method returns only the IDs for valid, non-corrupted transaction
        /// operation logs.  It will delete any corrupted logs it finds.
        /// </remarks>
        public List <Guid> GetOrphanTransactions()
        {
            var  orphans = new List <Guid>();
            Guid id;

            using (TimedLock.Lock(syncLock))
            {
                if (!isOpen)
                {
                    throw new TransactionException(NotOpenMsg);
                }

                foreach (string file in Helper.GetFilesByPattern(folder + Helper.PathSepString + "*.log", SearchOption.AllDirectories))
                {
                    if (FileOperationLog.Validate(file, out id))
                    {
                        orphans.Add(id);
                    }
                    else
                    {
                        try
                        {
                            File.Delete(file);
                        }
                        catch
                        {
                            // Ignore errors
                        }
                    }
                }

                return(orphans);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Opens the transaction log, returning a <see cref="LogStatus" />
        /// value indicating the state of the transaction log.
        /// </summary>
        /// <param name="manager">The <see cref="TransactionManager" />.</param>
        /// <returns>The log's <see cref="LogStatus" /> code.</returns>
        /// <remarks>
        /// <para>
        /// This method will return <see cref="LogStatus.Ready" /> if the log is ready to
        /// begin handling transactions.
        /// </para>
        /// <para>
        /// <see cref="LogStatus.Recover" /> will be returned if the log was not
        /// closed properly (probably due to a system or application failure) and
        /// there are transactions that need to be recovered.  The <see cref="TransactionManager" />
        /// will call <see cref="GetOrphanTransactions" /> to get the <see cref="Guid" />s of
        /// the orphaned transactions and will then call <see cref="OpenOperationLog" />
        /// to open each transaction operation log and then undo or redo the transaction
        /// operations depending on the state of the operation log.
        /// </para>
        /// <para>
        /// The method returns <see cref="LogStatus.Corrupt" /> if the transaction
        /// log is corrupt and that there's the potential for the resource to
        /// be in an inconsistent state after recovering the remaining transactions.
        /// </para>
        /// </remarks>
        /// <exception cref="TransactionException">Thrown if the log is already open.</exception>
        public LogStatus Open(TransactionManager manager)
        {
            bool orphans;
            Guid id;

            try
            {
                if (isOpen)
                {
                    throw new TransactionException("Transaction log is already open.");
                }

                Helper.CreateFolderTree(folder);
                lockFile = new FileStream(folder + Helper.PathSepString + "transactions.lock", FileMode.Create, FileAccess.ReadWrite);

                orphans = false;
                foreach (var file in Helper.GetFilesByPattern(folder + Helper.PathSepString + "*.log", SearchOption.AllDirectories))
                {
                    orphans = true;
                    if (!FileOperationLog.Validate(file, out id))
                    {
                        return(LogStatus.Corrupt);
                    }
                }

                isOpen   = true;
                syncLock = manager.SyncRoot;

                return(orphans ? LogStatus.Recover : LogStatus.Ready);
            }
            catch
            {
                if (lockFile != null)
                {
                    lockFile.Close();
                    lockFile = null;
                }

                throw;
            }
        }