/// <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"); } }
/// <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; }