/// <summary>
        /// Adds an <see cref="ExceptionLogEntry"/>.  If the <see cref="ExceptionLogEntry"/> cannot be created, the error is logged to the log file instead.
        /// </summary>
        /// <param name="operationName"></param>
        /// <param name="e"></param>
        public static void Log(string operationName, Exception e)
        {
            try
            {
                // log the error to the database
                using (PersistenceScope scope = new PersistenceScope(PersistenceContextType.Update, PersistenceScopeOption.RequiresNew))
                {
                    // disable change-set auditing for this context
                    ((IUpdateContext)PersistenceScope.CurrentContext).ChangeSetRecorder = null;

                    DefaultExceptionRecorder recorder = new DefaultExceptionRecorder();
                    ExceptionLogEntry        logEntry = recorder.CreateLogEntry(operationName, e);

                    PersistenceScope.CurrentContext.Lock(logEntry, DirtyState.New);

                    scope.Complete();
                }
            }
            catch (Exception x)
            {
                // if we fail to properly log the exception, there is nothing we can do about it
                // just log a message to the log file
                Platform.Log(LogLevel.Error, x);

                // also log the original exception to the log file, since it did not get logged to the DB
                Platform.Log(LogLevel.Error, e);
            }
        }
Example #2
0
        protected sealed override bool ClaimItem(TItem item)
        {
            try
            {
                using (var scope = new PersistenceScope(PersistenceContextType.Update))
                {
                    var context = (IUpdateContext)PersistenceScope.CurrentContext;
                    context.ChangeSetRecorder.OperationName = this.GetType().FullName;

                    // need to lock the item in context, to allow loading of extended properties collection by subclass
                    context.Lock(item);

                    // mark item as being in process
                    MarkItemClaimed(item);

                    // complete the transaction
                    scope.Complete();
                }
                return(true);
            }
            catch (EntityVersionException)
            {
                // if we get a version exception, the item has already been claimed by another process
                // this is not an error
                return(false);
            }
        }
Example #3
0
        protected sealed override IList <TItem> GetNextBatch(int batchSize)
        {
            using (var scope = new PersistenceScope(PersistenceContextType.Read))
            {
                var items = GetNextEntityBatch(batchSize);

                scope.Complete();
                return(items);
            }
        }
Example #4
0
        protected sealed override void ProcessItem(TItem item)
        {
            Exception error = null;

            using (var scope = new PersistenceScope(PersistenceContextType.Update))
            {
                var context = (IUpdateContext)PersistenceScope.CurrentContext;
                context.ChangeSetRecorder.OperationName = this.GetType().FullName;

                // need to lock the item in context, to allow loading of extended properties collection by subclass
                context.Lock(item);

                try
                {
                    // take action based on item
                    ActOnItem(item);

                    // ensure that the commit will ultimately succeed
                    context.SynchState();

                    // success callback
                    OnItemSucceeded(item);

                    // complete the transaction
                    scope.Complete();
                }
                catch (Exception e)
                {
                    // one of the actions failed
                    Platform.Log(LogLevel.Error, e);
                    error = e;
                }
            }

            // exceptions thrown upon exiting the using block above are intentionally not caught here,
            // allow them to be caught by the calling method

            // post-processing
            if (error == null)
            {
                AfterCommit(item);
            }
            else
            {
                UpdateItemOnError(item, error);
            }
        }
Example #5
0
        private void UpdateItemOnError(TItem item, Exception error)
        {
            // use a new scope to mark the item as failed, because we don't want to commit any changes made in the outer scope
            using (var scope = new PersistenceScope(PersistenceContextType.Update, PersistenceScopeOption.RequiresNew))
            {
                var failContext = (IUpdateContext)PersistenceScope.CurrentContext;
                failContext.ChangeSetRecorder.OperationName = this.GetType().FullName;

                // bug #7191 : Reload the TItem in this scope;  using the existing item results in NHibernate throwing a lazy loading exception
                var itemForThisScope = failContext.Load <TItem>(item.GetRef(), EntityLoadFlags.None);

                // lock item into this context
                failContext.Lock(itemForThisScope);

                // failure callback
                OnItemFailed(itemForThisScope, error);

                // complete the transaction
                scope.Complete();
            }
        }