///<summary> ///Called when the transaction has completed. ///</summary> /// ///<param name="items">An <see cref="T:System.Collections.ICollection"></see> of work items.</param> ///<param name="succeeded">true if the transaction succeeded; otherwise, false.</param> public void Complete(bool succeeded, ICollection items) { TraceHelper.Trace(); try { if (succeeded) { foreach (PendingWorkItem item in items) { if (item.Type == PendingWorkItem.ItemType.Instance && item.NextTimer != null) { this.smartTimer.Update(item.NextTimer.Value); } } WfLogHelper.WriteLog("持久化提交事务Complete完成......"); } } catch (Exception e) { WfLogHelper.WriteLog("持久化Complete务发生异常:" + e.ToString()); string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString()); TraceHelper.Trace(errorMessage); PersistenceException persistenceException = new PersistenceException(errorMessage, e); base.RaiseServicesExceptionNotHandledEvent( persistenceException, Guid.Empty); throw persistenceException; } }
///<summary> /// Load the specified workflow instance into memory from the /// persistence store. ///</summary> ///<param name="instanceId"> /// The <see cref="T:System.Guid"></see> of the root activity of the workflow instance. /// </param> protected override Activity LoadWorkflowInstanceState(Guid instanceId) { TraceHelper.Trace(); Activity rootActivity; try { using (IPersistenceResourceAccessor resourceAccessor = CreateAccessor(this.resourceProvider)) { byte[] instanceState = resourceAccessor.RetrieveInstanceState( instanceId, serviceId, OwnershipTimeout); rootActivity = RestoreFromDefaultSerializedForm(instanceState, null); } } catch (Exception e) { WfLogHelper.WriteLog("加载工作流状态实例发生异常:LoadWorkflowInstanceState(" + instanceId + ");异常信息:" + e.ToString()); string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString()); TraceHelper.Trace(errorMessage); PersistenceException persistenceException = new PersistenceException(errorMessage, e); base.RaiseServicesExceptionNotHandledEvent( persistenceException, instanceId); throw persistenceException; } return(rootActivity); }
/// <summary> /// Persist a workflow instance to the persistence store. /// </summary> /// <param name="rootActivity"> /// Root activity of the workflow instance. /// </param> /// <param name="unlock"> /// Indicates whether to unlock the instance when complete. /// </param> protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock) { TraceHelper.Trace(); try { if (rootActivity == null) { throw new ArgumentNullException("rootActivity"); } PendingWorkItem workItem = new PendingWorkItem(); workItem.Status = GetWorkflowStatus(rootActivity); workItem.IsBlocked = GetIsBlocked(rootActivity); workItem.Info = GetSuspendOrTerminateInfo(rootActivity); workItem.StateId = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty); workItem.Type = PendingWorkItem.ItemType.Instance; workItem.InstanceId = WorkflowEnvironment.WorkflowInstanceId; workItem.Unlock = unlock; if (workItem.Status != WorkflowStatus.Completed && workItem.Status != WorkflowStatus.Terminated) { workItem.SerialisedActivity = GetDefaultSerializedForm(rootActivity); } else { workItem.SerialisedActivity = new byte[0]; } TimerEventSubscription timerEventSubscription = ((TimerEventSubscriptionCollection)rootActivity.GetValue( TimerEventSubscriptionCollection.TimerCollectionProperty)).Peek(); if (timerEventSubscription == null) { workItem.NextTimer = null; } else { workItem.NextTimer = timerEventSubscription.ExpiresAt; } WorkflowEnvironment.WorkBatch.Add(this, workItem); } catch (Exception e) { WfLogHelper.WriteLog("持久化SaveWorkflowInstanceState发生异常:" + e.ToString()); string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString()); TraceHelper.Trace(errorMessage); PersistenceException persistenceException = new PersistenceException(errorMessage, e); base.RaiseServicesExceptionNotHandledEvent( persistenceException, WorkflowEnvironment.WorkflowInstanceId); throw persistenceException; } }
protected override void CommitWorkBatch(CommitWorkBatchCallback commitWorkBatchCallback) { TraceHelper.Trace(); Transaction transactionToUse; if (Transaction.Current == null) { transactionToUse = new CommittableTransaction(); WfLogHelper.WriteLog("CommitWorkBatch提交TransactionScope事务Transaction.Current==null"); } else { transactionToUse = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); WfLogHelper.WriteLog("CommitWorkBatch提交TransactionScope事务Transaction.Current!=null"); } TransactionCreated(transactionToUse); try { using (TransactionScope txScope = new TransactionScope(transactionToUse)) { commitWorkBatchCallback(); txScope.Complete(); WfLogHelper.WriteLog("CommitWorkBatch提交TransactionScope事务Complete完成......"); } CommittableTransaction committableTransaction = transactionToUse as CommittableTransaction; if (committableTransaction != null) { committableTransaction.Commit(); WfLogHelper.WriteLog("CommitWorkBatch提交committableTransaction事务Complete完成......"); } DependentTransaction dependentTransaction = transactionToUse as DependentTransaction; if (dependentTransaction != null) { dependentTransaction.Complete(); WfLogHelper.WriteLog("CommitWorkBatch提交dependentTransaction事务Complete完成......"); } WorkBatchCommitted(transactionToUse); } catch (Exception e) { transactionToUse.Rollback(e); WorkBatchRolledback(transactionToUse); throw; } finally { if (transactionToUse != null) { transactionToUse.Dispose(); } } }
/// <summary> /// Check to see whether the result of a persistence operation /// was successful, raise appropriate exceptions if not. /// </summary> /// <param name="dbCommand"> /// <see cref="DbCommand" /> to retrieve result information from. /// </param> /// <param name="resultParameter"> /// Name of the parameter storing the result. /// </param> /// <param name="instanceParameter"> /// Name of the parameter storing the instance identifier. /// </param> private void checkResult(DbCommand dbCommand, string resultParameter, string instanceParameter) { int?result = valueReader.GetNullableInt32(dbCommand, resultParameter); if (result == ownershipError) { Guid instanceId = valueReader.GetGuid(dbCommand, instanceParameter); WfLogHelper.WriteLog("检查结果:instanceId=" + instanceId.ToString()); throw new WorkflowOwnershipException(instanceId); } }
/// <summary> /// Retrieve instance state from the persistence store. /// </summary> /// <param name="instanceId"></param> /// <param name="ownerId"></param> /// <param name="ownedUntil"></param> /// <returns></returns> public byte[] RetrieveInstanceState(Guid instanceId, Guid ownerId, DateTime ownedUntil) { byte[] instanceState = null; using (DbCommand dbCommand = CreateCommand(nameResolver.ResolveCommandName(PersistenceCommandName.RetrieveInstanceState), CommandType.StoredProcedure)) { string instanceParameter = nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.InstanceId); string resultParameter = nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.Result); AddParameter(dbCommand, instanceParameter, instanceId, AdoDbType.Guid); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.RetrieveInstanceState, PersistenceParameterName.OwnerId), ownerId, AdoDbType.Guid); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.RetrieveInstanceState, PersistenceParameterName.OwnedUntil), ownedUntil, AdoDbType.DateTime); AddParameter(dbCommand, resultParameter, AdoDbType.Int32, ParameterDirection.Output); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.RetrieveInstanceState, PersistenceParameterName.CurrentOwnerId), AdoDbType.Guid, ParameterDirection.Output); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.RetrieveInstanceState, PersistenceParameterName.State), AdoDbType.Cursor, ParameterDirection.Output); int?result; using (IDataReader dataReader = dbCommand.ExecuteReader()) { if (dataReader.Read()) { instanceState = (byte[])valueReader.GetValue(dataReader, 0); } result = valueReader.GetNullableInt32(dbCommand, resultParameter); } if (instanceState == null && result > 0) { // workflow could not be found PersistenceException e = new PersistenceException( RM.Get_Error_InstanceCouldNotBeLoaded(instanceId)); e.Data["WorkflowNotFound"] = true; WfLogHelper.WriteLog("检索实例状态 public byte[] RetrieveInstanceState(" + instanceId + ", " + ownerId + ", " + ownedUntil + ")发生异常:" + e.ToString()); throw e; } else { checkResult(dbCommand, resultParameter, instanceParameter); } } return(instanceState); }
/// <summary> /// Insert instance state into the persistence store. /// </summary> /// <param name="workItem"></param> /// <param name="ownerId"></param> /// <param name="ownedUntil"></param> public void InsertInstanceState(PendingWorkItem workItem, Guid ownerId, DateTime ownedUntil) { WfLogHelper.WriteLog("持久化InsertInstanceState InstanceId=" + workItem.InstanceId + ";ownerId=" + ownerId + ";时间=" + ownedUntil); using (DbCommand dbCommand = CreateCommand(nameResolver.ResolveCommandName(PersistenceCommandName.InsertInstanceState), CommandType.StoredProcedure)) { string instanceParameter = nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.InstanceId); string resultParameter = nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.Result); AddParameter(dbCommand, instanceParameter, workItem.InstanceId, AdoDbType.Guid); //DbParameter dp= AddParameter(dbCommand, nameResolver.ResolveParameterName( // PersistenceCommandName.InsertInstanceState, // PersistenceParameterName.State), workItem.SerialisedActivity, // AdoDbType.Binary); #region beyond OracleCommand cmd2 = (OracleCommand)dbCommand.Connection.CreateCommand(); //OracleTransaction tx; //tx = conn.BeginTransaction(); //cmd2.Transaction = tx; cmd2.CommandText = "declare xx blob; begin dbms_lob.createtemporary(xx, false, 0); :tempblob := xx; end;"; cmd2.Parameters.Add(new OracleParameter("tempblob", OracleType.Blob)); cmd2.Parameters["tempblob"].Direction = ParameterDirection.Output; cmd2.ExecuteNonQuery(); OracleLob tempLob; tempLob = (OracleLob)cmd2.Parameters["tempblob"].Value; tempLob.BeginBatch(OracleLobOpenMode.ReadWrite); tempLob.Write(workItem.SerialisedActivity, 0, workItem.SerialisedActivity.Length); tempLob.EndBatch(); //dbCommand.Parameters.Add(new OracleParameter("p_STATE", OracleType.Blob)); OracleParameter p_STATE = new OracleParameter("p_STATE", OracleType.Blob); p_STATE.Direction = ParameterDirection.Input; p_STATE.Value = tempLob; dbCommand.Parameters.Add(p_STATE); #endregion AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.Status), workItem.Status, AdoDbType.Int32); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.Unlock), workItem.Unlock, AdoDbType.Boolean); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.IsBlocked), workItem.IsBlocked, AdoDbType.Boolean); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.Info), workItem.Info, AdoDbType.Text); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.OwnerId), ownerId, AdoDbType.Guid); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.OwnedUntil), ownedUntil.ToUniversalTime(), AdoDbType.DateTime); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.NextTimer), workItem.NextTimer, AdoDbType.DateTime); AddParameter(dbCommand, resultParameter, AdoDbType.Int32, ParameterDirection.Output); AddParameter(dbCommand, nameResolver.ResolveParameterName( PersistenceCommandName.InsertInstanceState, PersistenceParameterName.CurrentOwnerId), AdoDbType.Guid, ParameterDirection.Output); dbCommand.ExecuteNonQuery(); checkResult(dbCommand, resultParameter, instanceParameter); } }
///<summary> ///Commits the list of work items by using the specified <see cref="T:System.Transactions.Transaction"></see> object. ///</summary> /// ///<param name="items">The work items to be committed.</param> ///<param name="transaction">The <see cref="T:System.Transactions.Transaction"></see> associated with the pending work.</param> public void Commit(Transaction transaction, ICollection items) { TraceHelper.Trace(); if (transaction == null) { throw new ArgumentNullException("transaction"); } if (items == null) { throw new ArgumentNullException("items"); } try { using (IPersistenceResourceAccessor resourceAccessor = CreateAccessor(this.resourceProvider, transaction)) { foreach (PendingWorkItem item in items) { switch (item.Type) { case PendingWorkItem.ItemType.Instance: resourceAccessor.InsertInstanceState(item, serviceId, this.OwnershipTimeout); continue; case PendingWorkItem.ItemType.CompletedScope: resourceAccessor.InsertCompletedScope( item.InstanceId, item.StateId, item.SerialisedActivity); continue; case PendingWorkItem.ItemType.ActivationComplete: resourceAccessor.UnlockInstanceState( item.InstanceId, this.serviceId); continue; } } } WfLogHelper.WriteLog("持久化提交事务Commit完成......"); } catch (Exception e) { WfLogHelper.WriteLog("持久化提交事务Commit发生异常:" + e.ToString()); string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString()); TraceHelper.Trace(errorMessage); PersistenceException persistenceException = new PersistenceException(errorMessage, e); base.RaiseServicesExceptionNotHandledEvent( persistenceException, Guid.Empty); throw persistenceException; } }