public void TransactionDispose3 () { CommittableTransaction ct = new CommittableTransaction (); IntResourceManager irm = new IntResourceManager (1); try { Transaction.Current = ct; irm.Value = 5; ct.Commit (); ct.Dispose (); } finally { Transaction.Current = null; } irm.Check (1, 1, 0, 0, "Dispose transaction"); Assert.AreEqual (5, irm.Value); }
private void EmployWorkersForJob(RunningJob runningJob) { foreach (JobSection jobSection in runningJob.Sections) { if (null == jobSection.WorkerCard) continue; // We don't have workers for this role uint availableWorkers = jobSection.WorkerCard.MaxNumOfInstances - GetWorkingWorkersNumber(jobSection.RoleType); if (availableWorkers == 0) continue; // All available workers for that role are busy // Try to hire ONE worker for the role. // We should not hire more than one worker for the role in one iteration to give other WorkerManagers a chance to take some workload. RoleSlotToken roleSlotToken = null; var transaction = new CommittableTransaction(TransactionManager.MaximumTimeout); Transaction oldAmbient = Transaction.Current; Transaction.Current = transaction; try { roleSlotToken = jobSection.GetFreeSlot(); } finally { Transaction.Current = oldAmbient; if (null == roleSlotToken) { transaction.Rollback(); transaction.Dispose(); } } if (null == roleSlotToken) { continue; } WorkAssignment workAssignment = new WorkAssignment(jobSection.WorkRequest, roleSlotToken, runningJob.JobId, runningJob.ScheduleRunDuration, runningJob.ScheduleCreatedBy, runningJob.NotificationId, runningJob.Frequency); EmployWorker(jobSection.WorkerCard, workAssignment, transaction); jobSection.WorkerIDs.Add(workAssignment.WorkerId); } }
/// <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 TransactionDispose () { CommittableTransaction ct = new CommittableTransaction (); IntResourceManager irm = new IntResourceManager (1); irm.Type = ResourceManagerType.Durable; ct.Dispose (); irm.Check (0, 0, 0, 0, "Dispose transaction"); }
public override int Insert(DataTable dt, DataColumnCollection colinfo, params string[] ignoreFields) { /* insert into Managers(ManagerName) select 'a' union all select 'b' union all select 'c' */ int rlt = 0; int vNextSubmitValue = vSubmitCount; string sqlmain = "insert into {0} ({1}) {2}"; string sqlsel = " union all select {0} "; string cols = "", sels = "", sql; string tname = SqlHelper.MakeSafeFieldNameSql(dt.TableName); int i = 0; LastException = null; foreach (DataColumn col in dt.Columns) { if (!ignoreFields.Contains<string>(col.ColumnName)) { cols += "," + SqlHelper.MakeSafeFieldNameSql(col.ColumnName); } } cols = cols.Substring(1); CommittableTransaction ts = new CommittableTransaction(); DbConnection conn = db.GetConnection(); conn.Open(); conn.EnlistTransaction(ts); while (i < dt.Rows.Count) { for (; i < dt.Rows.Count; i++) { DataRow row = dt.Rows[i]; string vals = ""; foreach (DataColumn col in dt.Columns) { if (!ignoreFields.Contains<string>(col.ColumnName)) { string val = row[col].ToString(); vals += "," + SqlHelper.MakeSafeFieldSql(val, colinfo, col) + " "; } } sels += string.Format(sqlsel, vals.Substring(1)); if (i + 1 >= vNextSubmitValue) { vNextSubmitValue += vSubmitCount; break; } } sels = sels.Substring(11); sql = string.Format(sqlmain, tname, cols, sels); Logger.Log(sql); ExecuteResult er = db.Execute(sql, conn, ts); rlt += er.IntRlt; if (er.Exception != null) { rlt = 0; LastException = er.Exception; break; } sels = ""; i++; } if (rlt != 0 && LastException == null) { ts.Commit(); } if (conn.State != ConnectionState.Closed) { conn.Close(); } ts.Dispose(); return rlt; }
internal static void SafeRollbackTransaction(CommittableTransaction transaction) { if (transaction != null) { try { transaction.Rollback(); transaction.Dispose(); } catch (TransactionException transactionException) { if (TD.RoutingServiceHandledExceptionIsEnabled()) { TD.RoutingServiceHandledException(null, transactionException); } } catch (ObjectDisposedException disposedException) { if (TD.RoutingServiceHandledExceptionIsEnabled()) { TD.RoutingServiceHandledException(null, disposedException); } } } }
public override int Delete(DataTable dt, string fname, DataColumnCollection colinfo) { int rlt = 0; string sqlmain = "delete from {0} "; string sqlwhere = " where {0} in ({1}) "; string sql, where, ids = ""; LastException = null; foreach (DataRow row in dt.Rows) { if (dt.Columns.Contains(fname)) { ids += "," + SqlHelper.MakeSafeFieldSql(row[fname].ToString(), colinfo[fname].ToString(), true); } } ids = ids.Substring(1); where = string.Format(sqlwhere, SqlHelper.MakeSafeFieldNameSql(fname), ids); sql = string.Format(sqlmain, SqlHelper.MakeSafeFieldNameSql(dt.TableName)) + where; Logger.Log(sql); CommittableTransaction ts = new CommittableTransaction(); DbConnection conn = db.GetConnection(); conn.Open(); conn.EnlistTransaction(ts); ExecuteResult er = db.Execute(sql, conn, ts); rlt = er.IntRlt; if (er.Exception != null) { LastException = er.Exception; rlt = 0; } else { ts.Commit(); } if (conn.State != ConnectionState.Closed) { conn.Close(); } ts.Dispose(); return rlt; }
public override int Update(DataTable dt, string fname, DataColumnCollection colinfo, params string[] ignoreFields) { /* UPDATE Managers SET ManagerName = CASE id WHEN 6 THEN 'value' WHEN 7 THEN 'value' WHEN 8 THEN 'value' END WHERE id IN (6,7,8)" */ int rlt = 0; int vNextSubmitValue = vSubmitCount; string sqlmain = "update {0} set {1} "; string sqlset = " , {0} = case {1} {2} end "; string sqlwhen = " when {0} then {1} "; string sqlwhere = " where {0} in ({1}) "; string sets = "", ids = "", sql, where, whens; string tname = SqlHelper.MakeSafeFieldNameSql(dt.TableName); int i = 0, n = 0; LastException = null; CommittableTransaction ts = new CommittableTransaction(); DbConnection conn = db.GetConnection(); conn.Open(); conn.EnlistTransaction(ts); while (i < dt.Rows.Count) { foreach (DataColumn col in dt.Columns) { whens = ""; //foreach (DataRow row in dt.Rows) for (i = vNextSubmitValue - vSubmitCount; i < vNextSubmitValue; i++) { DataRow row = dt.Rows[i]; if (!col.ColumnName.Equals(fname)) { whens += string.Format(sqlwhen , SqlHelper.MakeSafeFieldSql(row[fname].ToString(), colinfo, dt.Columns[fname]) , SqlHelper.MakeSafeFieldSql(row[col].ToString(), colinfo, col)); } else { ids += "," + SqlHelper.MakeSafeFieldSql(row[col].ToString(), colinfo, col); } if (i + 1 >= vNextSubmitValue) { break; } else if (i + 1 >= dt.Rows.Count) { break; } } if (!col.ColumnName.Equals(fname)) { if (ignoreFields.Contains<string>(col.ColumnName)) { continue; } sets += string.Format(sqlset, SqlHelper.MakeSafeFieldNameSql(col.ColumnName), SqlHelper.MakeSafeFieldNameSql(fname), whens); } } sets = sets.Substring(2); ids = ids.Substring(1); where = string.Format(sqlwhere, fname, ids); sql = string.Format(sqlmain, tname, sets) + where; Logger.Log(sql); ExecuteResult er = db.Execute(sql, conn, ts); rlt += er.IntRlt; if (er.Exception != null) { rlt = 0; LastException = er.Exception; break; } //rlt += Execute(sql, conn, ts); //if (LastException != null) //{ // rlt = 0; // break; //} sets = ""; where = ""; ids = ""; vNextSubmitValue += vSubmitCount; if (i + 1 >= dt.Rows.Count) { break; } } if (rlt != 0 && LastException == null) { ts.Commit(); } if (conn.State != ConnectionState.Closed) { conn.Close(); } ts.Dispose(); return rlt; }
public void TransactionDispose () { CommittableTransaction ct = new CommittableTransaction (); IntResourceManager irm = new IntResourceManager (1); irm.Volatile = false; ct.Dispose (); irm.Check (0, 0, 0, 0, "Dispose transaction"); }
/// <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; }
public static void ListenerThreadProc(object queueListenerConfig) { QueueListenerConfig config = (QueueListenerConfig) queueListenerConfig; while (!stopping) { TransactionOptions to = new TransactionOptions(); to.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; to.Timeout = TimeSpan.MaxValue; CommittableTransaction tran = new CommittableTransaction(to); try { using (var con = new SqlConnection(config.ConnectionString)) { con.Open(); con.EnlistTransaction(tran); byte[] message = ServiceBrokerUtils.GetMessage(config.QueueName, con, TimeSpan.FromSeconds(10)); if (message == null) //no message available { tran.Commit(); con.Close(); continue; } try { if (config.EnlistMessageProcessor) { using (var ts = new TransactionScope(tran)) { config.MessageProcessor(message); ts.Complete(); } } else { config.MessageProcessor(message); } } catch (SqlException ex) //catch selected exceptions thrown by the MessageProcessor { config.FailedMessageProcessor(message, con, ex); } tran.Commit(); // the message processing succeeded or the FailedMessageProcessor ran so commit the RECEIVE con.Close(); } } catch (SqlException ex) { System.Diagnostics.Trace.Write("Error processing message from " + config.QueueName + ": " + ex.Message); tran.Rollback(); tran.Dispose(); Thread.Sleep(1000); } ///catch any other non-fatal exceptions that should not stop the listener loop. catch (Exception ex) { Trace.WriteLine("Unexpected Exception in Thread Proc for " + config.QueueName + ". Thread Proc is exiting: " + ex.Message); tran.Rollback(); tran.Dispose(); return; } } }