/// <summary>
        /// 
        /// </summary>
        /// <returns>Retrieved work item or null if not found, didn't pass pre-check, etc.</returns>
        private WorkItem GetWorkItemFromQueue
            ()
        {
            //TODO: Pay great attention here, now workItemCandidate is an instance field!!! (SD)
            workItemCandidate = null;

            #region Get message from queue

            var transaction = new CommittableTransaction();

            try
            {

                Job job;


                using (DependentTransaction dependentTransaction =
                    transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete))
                {
                    using (var scope = new TransactionScope(dependentTransaction))
                    {
                        job = ItemProvider.GetNextItem();
                        scope.Complete();
                    }

                    dependentTransaction.Complete();
                }

                if (job != null)
                {
                    PerformanceHandler.HandleEvent("Reads From Queue/sec", 1);

                    workItemCandidate = new RequestWorkItem(job.ContextIdentifier.InternalId,
                                                            0, WorkItemState.AvailableForProcessing,
                                                            SubmissionPriority.Normal, null, false, false, "test",
                                                            new ContextIdentifier());
                    // Set transaction on the work item
                    workItemCandidate.Transaction = transaction;
                    workItemCandidate.RetrievedAt = DateTime.Now;
                    workItemCandidate.MessageBody = SerializationUtility.Serialize2ByteArray(job);
                }
                else
                {
                    workItemCandidate = null;
                }

                FailureExceptionHandler.ResetState();
            }
            catch (Exception ex)
            {
                try
                {
                    // Rollback the commitable transaction
                    transaction.Rollback(ex);
                }
                finally
                {
                    transaction.Dispose();
                }

                Log.Source.TraceData(TraceEventType.Error,
                                     ProducerMessage.ErrorDuringObtainingTheWorkItem,
                                     new ContextualLogEntry
                                         {
                                             Message =
                                                 "Exception happened when trying to get item from the message queue (" +
                                                 "queue.QueuePath" + "). " + Environment.NewLine + ex
                                             ,
                                             ContextIdentifier =
                                                 ((workItemCandidate != null)
                                                      ? workItemCandidate.ContextIdentifier
                                                      :
                                                          new ContextIdentifier())
                                         });
                // To review what is the required handling here for us (SD)
                if (ExecutionState == ProcessExecutionState.Running)
                {
                    FailureExceptionType type = FailureExceptionHandler.HandleFailure(ex);
                    if (type == FailureExceptionType.NonRecoverable)
                        Stop();
                }
                else
                {
                    if (workItemCandidate != null)
                    {
                        Log.Source.TraceData(TraceEventType.Information,
                                             ProducerMessage.RetrievedMessageReturnedToTheRetrievalQueue,
                                             new ContextualLogEntry
                                                 {
                                                     Message =
                                                         string.Format
                                                         (
                                                         "'{0}': Retrieved Recurrence(Id = {1}) Successfully Saved to the {2} queue",
                                                         Name,
                                                         workItemCandidate.Id,
                                                         ""
                                                         ),
                                                     ContextIdentifier = workItemCandidate.ContextIdentifier
                                                 });
                        return null;
                    }
                }
                if (workItemCandidate == null) return null;
            }

            #endregion Get message from queue

            #region Pre-processing checks

            WorkItem workItem = AssignWorkItemFromCandidate(workItemCandidate);

            #endregion Pre-processing checks

            // Return retrieved work item (or null)
            return workItem;
        }
		public void ExplicitTransactionWithDependentTransaction()
		{
			using (var t = new CommittableTransaction())
			using (new TxScope(t, NullLogger.Instance))
			{
				Console.WriteLine("T1 STATUS: {0}", t.TransactionInformation.Status);

				using (var c = GetConnection())
				using (var cmd = c.CreateCommand())
				{
					cmd.CommandText = "SELECT TOP 1 Val FROM Thing";
					var scalar = (double)cmd.ExecuteScalar();
					Console.WriteLine("T1 STATUS: {0}", t.TransactionInformation.Status);
					Console.WriteLine("got val {0}, disposing command and connection", scalar);
				}

				using (var t2 = t.DependentClone(DependentCloneOption.RollbackIfNotComplete))
				using (new TxScope(t2, NullLogger.Instance))
				using (var c = GetConnection())
				using (var cmd = c.CreateCommand())
				{
					t2.TransactionCompleted +=
						(s, ea) =>
						Console.WriteLine("::: T2 TransactionCompleted: {0}", ea.Transaction.TransactionInformation.LocalIdentifier);
					cmd.CommandText = "DELETE FROM Thing";
					Console.WriteLine("T2: EXECUTING NON QUERY");
					cmd.ExecuteNonQuery();

					Console.WriteLine("T2: Enlisting volatile");
					t2.EnlistVolatile(new VolatileResource(false), EnlistmentOptions.None);

					Console.WriteLine("T2: COMPLETE-CALL");
					t2.Complete();
					Console.WriteLine("T2 STATUS: {0}", t2.TransactionInformation.Status);
				}

				Console.WriteLine("T1: COMMITTING, status: {0}", t.TransactionInformation.Status);
				try
				{
					t.Commit();
				}
				catch (TransactionAbortedException e)
				{
					Console.WriteLine("TransactionAbortedException, {0}", e);
					t.Rollback(e);
				}
				Console.WriteLine("T1 STATUS: {0}", t.TransactionInformation.Status);
				Console.WriteLine("T1: DISPOSING");
			}
		}
Пример #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="priority"></param>
        /// <returns>Retrieved work item or null if not found, didn't pass pre-check, etc.</returns>
        private WorkItem GetWorkItemFromQueue(SubmissionPriority priority)
        {
            //TODO: Pay great attention here, now workItemCandidate is an instance field!!! (SD)
            workItemCandidate = null;
            WorkItem workItem = null;
            Tools.Commands.Implementation.IF1.req item = null;

            Trace.CorrelationManager.ActivityId = Guid.NewGuid();


            #region Get message from queue

            var transaction = new CommittableTransaction();

            try
            {
                #region Get next job from the queue

                //var 

                using (DependentTransaction dependentTransaction =
                    transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete))
                {
                    using (var scope = new TransactionScope(dependentTransaction))
                    {
                        //TODO: (SD) Provide timeout option
                        item = new Tools.Commands.Implementation.IF1.req
                        {
                            reqId = (++IdSequence).ToString(),
                            processingStatus = "P",
                            errorDesc = "ok",
                            returnValue = "ok",
                            updateMechanism = "JMS"
                        }; 
                        
                        scope.Complete();
                    }

                    dependentTransaction.Complete();

                    if (item == null)
                    {
                        // if token is equal to null then commit here, as 
                        // consumer will not get to the item anyway.
                        if (transaction.TransactionInformation.Status == TransactionStatus.Active)
                            transaction.Commit();
                    }
                }

                #endregion

                #region If job is not null create a work item for it

                if (item != null)
                {
                    workItemCandidate = new RequestWorkItem(0, 0, WorkItemState.AvailableForProcessing,
                        SubmissionPriority.Normal, Encoding.UTF8.GetBytes(SerializationUtility.Serialize2String(item)), false, false, this.Name,
                        new ContextIdentifier { InternalId = 0, ExternalReference = IdSequence.ToString(), ExternalId = IdSequence.ToString() })
                        {
                            Transaction = transaction,
                            RetrievedAt = DateTime.Now
                        };

                    //**Trace.CorrelationManager.ActivityId = .ContextUid;
                    Log.Source.TraceEvent(TraceEventType.Start, 0, "Received the item " + item);

                    // Set transaction on the work item
                }

                #endregion

                this.FailureExceptionHandler.ResetState();
            }
            catch (Exception ex)
            {

                try
                {

                    // Rollback the commitable transaction
                    transaction.Rollback(ex);
                }
                finally
                {
                    transaction.Dispose();
                }

                Log.TraceData(Log.Source,
                    TraceEventType.Error,
                    ProducerMessage.ErrorDuringObtainingTheWorkItem,
                    new ContextualLogEntry
                    {
                        Message =
                            "Exception happened when trying to get item " + Environment.NewLine + ex,
                        ContextIdentifier = ((workItemCandidate != null) ? workItemCandidate.ContextIdentifier : new ContextIdentifier())
                    });

                // To review what is the required handling here for us (SD)
                if (ExecutionState == ProcessExecutionState.Running)
                {
                    FailureExceptionType type = this.FailureExceptionHandler.HandleFailure(ex);
                    if (type == FailureExceptionType.NonRecoverable)
                        this.Stop();
                }
                else
                {
                    if (workItemCandidate != null)
                    {
                        Log.TraceData(Log.Source, System.Diagnostics.TraceEventType.Information,
                            ProducerMessage.RetrievedMessageReturnedToTheRetrievalQueue,
                            new ContextualLogEntry
                            {
                                Message = string.Format(
                                    "'{0}': Retrieved Recurrence(Id = {1}) Successfully Saved to the {2} queue",
                                    Name,
                                    workItemCandidate.Id,
                                    ""
                                    ),
                                ContextIdentifier = workItemCandidate.ContextIdentifier
                            });
                        return null;
                    }
                }
            }

            #endregion Get message from queue

            #region Pre-processing checks

            // Convert queue message to work item
            // In case sql broker no need to do (SD)
            if (workItemCandidate != null)
            {
                #region WorkItem Diagnostics

                workItemCandidate.AttachNote("Received from the " + priority + " Queue ");

                #endregion WorkItem Diagnostics

                // TODO: //**SD1 - Provide the check for 

                // No checks done now, see the DB driven implementation for the checks samples (SD)
                // It means as well that we can simply assign item candidate to be our work item
                workItem = workItemCandidate;

                // TODO: (SD) Message body will be the xml retrieved from the sql broker
                //**message.GetObjectProperty
            }

            #endregion Pre-processing checks

            // Return retrieved work item (or null)
            return workItem;
        }