Beispiel #1
0
        internal IAsyncResult BeginTryCommandInternal(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {
            SqlWorkflowInstanceStoreAsyncResult result = null;

            if (command is SaveWorkflowCommand)
            {
                result = new SaveWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is TryLoadRunnableWorkflowCommand)
            {
                result = new TryLoadRunnableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is LoadWorkflowCommand)
            {
                result = new LoadWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is LoadWorkflowByInstanceKeyCommand)
            {
                result = new LoadWorkflowByKeyAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is ExtendLockCommand)
            {
                result = new ExtendLockAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
            }
            else if (command is DetectRunnableInstancesCommand)
            {
                result = new DetectRunnableInstancesAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
            }
            else if (command is DetectActivatableWorkflowsCommand)
            {
                result = new DetectActivatableWorkflowsAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
            }
            else if (command is RecoverInstanceLocksCommand)
            {
                result = new RecoverInstanceLocksAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
            }
            else if (command is UnlockInstanceCommand)
            {
                result = new UnlockInstanceAsyncResult(null, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is CreateWorkflowOwnerCommand)
            {
                result = new CreateWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is DeleteWorkflowOwnerCommand)
            {
                result = new DeleteWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else if (command is QueryActivatableWorkflowsCommand)
            {
                result = new QueryActivatableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
            }
            else
            {
                return(base.BeginTryCommand(context, command, timeout, callback, state));
            }
            result.ScheduleCallback();
            return(result);
        }
 internal IAsyncResult BeginTryCommandInternal(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
 {
     SqlWorkflowInstanceStoreAsyncResult result = null;
     if (command is SaveWorkflowCommand)
     {
         result = new SaveWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is TryLoadRunnableWorkflowCommand)
     {
         result = new TryLoadRunnableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is LoadWorkflowCommand)
     {
         result = new LoadWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is LoadWorkflowByInstanceKeyCommand)
     {
         result = new LoadWorkflowByKeyAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is ExtendLockCommand)
     {
         result = new ExtendLockAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is DetectRunnableInstancesCommand)
     {
         result = new DetectRunnableInstancesAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is DetectActivatableWorkflowsCommand)
     {
         result = new DetectActivatableWorkflowsAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is RecoverInstanceLocksCommand)
     {
         result = new RecoverInstanceLocksAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is UnlockInstanceCommand)
     {
         result = new UnlockInstanceAsyncResult(null, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is CreateWorkflowOwnerCommand)
     {
         result = new CreateWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is DeleteWorkflowOwnerCommand)
     {
         result = new DeleteWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is QueryActivatableWorkflowsCommand)
     {
         result = new QueryActivatableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else
     {
         return base.BeginTryCommand(context, command, timeout, callback, state);
     }
     result.ScheduleCallback();
     return result;
 }
        static void AddSerializedProperty(ArraySegment <byte> source, SqlParameterCollection parameters, string parameterName)
        {
            int    parameterSize  = source.Count > 8000 ? source.Count : -1;
            object parameterValue = (parameterSize == -1 ? SaveWorkflowAsyncResult.GenerateByteArray(source) : source.Array) ?? (object)DBNull.Value;

            parameters.Add(new SqlParameter {
                ParameterName = parameterName, SqlDbType = SqlDbType.VarBinary, Size = parameterSize, Value = parameterValue
            });
        }
        protected override Exception ProcessSqlResult(SqlDataReader reader)
        {
            Exception exception = StoreUtilities.GetNextResultSet(base.InstancePersistenceCommand.Name, reader);

            if (exception == null)
            {
                SaveWorkflowCommand  saveWorkflowCommand  = base.InstancePersistenceCommand as SaveWorkflowCommand;
                InstanceLockTracking instanceLockTracking = (InstanceLockTracking)(base.InstancePersistenceContext.UserContext);
                if ((this.serviceDeploymentHash != Guid.Empty) && (this.serviceDeploymentId == 0))
                {
                    this.serviceDeploymentId = reader.GetInt64(1);
                    PutServiceDeploymentId();
                    exception = StoreUtilities.GetNextResultSet(base.InstancePersistenceCommand.Name, reader);
                }

                if (exception == null)
                {
                    if (!base.InstancePersistenceContext.InstanceView.IsBoundToLock)
                    {
                        long instanceVersion = reader.GetInt64(1);
                        instanceLockTracking.TrackStoreLock(base.InstancePersistenceContext.InstanceView.InstanceId, instanceVersion, this.DependentTransaction);
                        base.InstancePersistenceContext.BindAcquiredLock(instanceVersion);
                    }

                    if (saveWorkflowCommand.InstanceData.Count > 0)
                    {
                        base.InstancePersistenceContext.PersistedInstance(saveWorkflowCommand.InstanceData);
                    }

                    SaveWorkflowAsyncResult.UpdateKeyData(base.InstancePersistenceContext, saveWorkflowCommand);

                    foreach (KeyValuePair <XName, InstanceValue> property in saveWorkflowCommand.InstanceMetadataChanges)
                    {
                        base.InstancePersistenceContext.WroteInstanceMetadataValue(property.Key, property.Value);
                    }

                    if (saveWorkflowCommand.CompleteInstance)
                    {
                        base.InstancePersistenceContext.CompletedInstance();
                    }

                    if (saveWorkflowCommand.UnlockInstance || saveWorkflowCommand.CompleteInstance)
                    {
                        instanceLockTracking.TrackStoreUnlock(this.DependentTransaction);
                        base.InstancePersistenceContext.InstanceHandle.Free();
                    }
                }
                else if (exception is InstanceLockLostException)
                {
                    base.InstancePersistenceContext.InstanceHandle.Free();
                }
            }

            return(exception);
        }
        void SerializePromotedProperties(SqlParameterCollection parameters, StringBuilder commandTextBuilder, SaveWorkflowCommand saveWorkflowCommand)
        {
            const int    SqlVariantStartColumn  = 1;
            const string promotionNameParameter = "@promotionName=";
            const string instanceIdParameter    = "@instanceId=";
            int          promotionNumber        = 0;

            foreach (KeyValuePair <string, Tuple <List <XName>, List <XName> > > promotion in base.Store.Promotions)
            {
                StringBuilder storedProcInvocationBuilder = new StringBuilder(SqlWorkflowInstanceStoreConstants.DefaultStringBuilderCapacity);
                int           column                = SqlVariantStartColumn;
                bool          addPromotion          = false;
                string        promotionNameArgument = string.Format(CultureInfo.InvariantCulture, "@promotionName{0}", promotionNumber);
                string        instanceIdArgument    = string.Format(CultureInfo.InvariantCulture, "@instanceId{0}", promotionNumber);

                storedProcInvocationBuilder.Append(string.Format(CultureInfo.InvariantCulture, "exec {0}.[InsertPromotedProperties] ", SqlWorkflowInstanceStoreConstants.DefaultSchema));
                storedProcInvocationBuilder.Append(promotionNameParameter);
                storedProcInvocationBuilder.Append(promotionNameArgument);
                storedProcInvocationBuilder.Append(",");
                storedProcInvocationBuilder.Append(instanceIdParameter);
                storedProcInvocationBuilder.Append(instanceIdArgument);

                foreach (XName name in promotion.Value.Item1)
                {
                    InstanceValue propertyValue;

                    if (saveWorkflowCommand.InstanceData.TryGetValue(name, out propertyValue))
                    {
                        if (!SerializationUtilities.IsPropertyTypeSqlVariantCompatible(propertyValue))
                        {
                            throw FxTrace.Exception.AsError(new InstancePersistenceException(SR.CannotPromoteAsSqlVariant(propertyValue.Value.GetType().ToString(), name.ToString())));
                        }

                        string parameterName = string.Format(CultureInfo.InvariantCulture, "@value{0}=", column);
                        string argumentName  = string.Format(CultureInfo.InvariantCulture, "@value{0}_promotion{1}", column, promotionNumber);
                        parameters.Add(new SqlParameter()
                        {
                            SqlDbType = SqlDbType.Variant, ParameterName = argumentName, Value = propertyValue.Value ?? DBNull.Value
                        });

                        storedProcInvocationBuilder.Append(", ");
                        storedProcInvocationBuilder.Append(parameterName);
                        storedProcInvocationBuilder.Append(argumentName);
                        addPromotion = true;
                    }
                    column++;
                }

                column = SqlVariantStartColumn + SqlWorkflowInstanceStoreConstants.MaximumPropertiesPerPromotion;

                foreach (XName name in promotion.Value.Item2)
                {
                    InstanceValue     propertyValue;
                    IObjectSerializer serializer = ObjectSerializerFactory.GetObjectSerializer(base.Store.InstanceEncodingOption);

                    if (saveWorkflowCommand.InstanceData.TryGetValue(name, out propertyValue))
                    {
                        string parameterName = string.Format(CultureInfo.InvariantCulture, "@value{0}=", column);
                        string argumentName  = string.Format(CultureInfo.InvariantCulture, "@value{0}_promotion{1}", column, promotionNumber);

                        SaveWorkflowAsyncResult.AddSerializedProperty(serializer.SerializeValue(propertyValue.Value), parameters, argumentName);
                        storedProcInvocationBuilder.Append(", ");
                        storedProcInvocationBuilder.Append(parameterName);
                        storedProcInvocationBuilder.Append(argumentName);
                        addPromotion = true;
                    }
                    column++;
                }

                if (addPromotion)
                {
                    parameters.Add(new SqlParameter()
                    {
                        SqlDbType = SqlDbType.NVarChar, Size = 400, ParameterName = promotionNameArgument, Value = promotion.Key
                    });
                    parameters.Add(new SqlParameter()
                    {
                        SqlDbType = SqlDbType.UniqueIdentifier, ParameterName = instanceIdArgument, Value = base.InstancePersistenceContext.InstanceView.InstanceId
                    });
                    storedProcInvocationBuilder.Append(";");
                    commandTextBuilder.AppendLine(storedProcInvocationBuilder.ToString());
                    promotionNumber++;
                }
            }
        }
        void SerializeAssociatedData(SqlParameterCollection parameters, SaveWorkflowCommand saveWorkflowCommand, StringBuilder commandTextBuilder)
        {
            if (saveWorkflowCommand.CompleteInstance && base.Store.InstanceCompletionAction == InstanceCompletionAction.DeleteAll)
            {
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToAssociate", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@singleKeyId", SqlDbType = SqlDbType.UniqueIdentifier, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToComplete", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToFree", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@concatenatedKeyProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@primitiveDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@complexDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@writeOnlyPrimitiveDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@writeOnlyComplexDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@metadataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@metadataIsConsistent", SqlDbType = SqlDbType.Bit, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@encodingOption", SqlDbType = SqlDbType.TinyInt, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@lastMachineRunOn", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@executionStatus", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@blockingBookmarks", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });

                return;
            }

            List <CorrelationKey> keysToAssociate = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToAssociate, base.Store.InstanceEncodingOption);
            List <CorrelationKey> keysToComplete  = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToComplete);
            List <CorrelationKey> keysToFree      = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToFree);

            ArraySegment <byte>[] dataProperties     = SerializationUtilities.SerializePropertyBag(saveWorkflowCommand.InstanceData, base.Store.InstanceEncodingOption);
            ArraySegment <byte>   metadataProperties = SerializationUtilities.SerializeMetadataPropertyBag(saveWorkflowCommand, base.InstancePersistenceContext, base.Store.InstanceEncodingOption);

            byte[] concatenatedKeyProperties = SerializationUtilities.CreateKeyBinaryBlob(keysToAssociate);
            bool   metadataConsistency       = (base.InstancePersistenceContext.InstanceView.InstanceMetadataConsistency == InstanceValueConsistency.None);
            bool   singleKeyToAssociate      = (keysToAssociate != null && keysToAssociate.Count == 1);

            parameters.Add(new SqlParameter {
                ParameterName = "@keysToAssociate", SqlDbType = SqlDbType.Xml, Value = singleKeyToAssociate ? DBNull.Value : SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToAssociate)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@singleKeyId", SqlDbType = SqlDbType.UniqueIdentifier, Value = singleKeyToAssociate ? keysToAssociate[0].KeyId : (object)DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@keysToComplete", SqlDbType = SqlDbType.Xml, Value = SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToComplete)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@keysToFree", SqlDbType = SqlDbType.Xml, Value = SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToFree)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@concatenatedKeyProperties", SqlDbType = SqlDbType.VarBinary, Size = -1, Value = (object)concatenatedKeyProperties ?? DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@metadataIsConsistent", SqlDbType = SqlDbType.Bit, Value = metadataConsistency
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@encodingOption", SqlDbType = SqlDbType.TinyInt, Value = base.Store.InstanceEncodingOption
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@lastMachineRunOn", SqlDbType = SqlDbType.NVarChar, Size = 450, Value = SqlWorkflowInstanceStoreConstants.MachineName
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@executionStatus", SqlDbType = SqlDbType.NVarChar, Size = 450, Value = GetExecutionStatus(saveWorkflowCommand) ?? (object)DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@blockingBookmarks", SqlDbType = SqlDbType.NVarChar, Size = -1, Value = GetBlockingBookmarks(saveWorkflowCommand) ?? (object)DBNull.Value
            });

            ArraySegment <byte>[] properties = { dataProperties[0], dataProperties[1], dataProperties[2], dataProperties[3], metadataProperties };
            string[] dataPropertyParameters  = { "@primitiveDataProperties", "@complexDataProperties", "@writeOnlyPrimitiveDataProperties", @"writeOnlyComplexDataProperties", "@metadataProperties" };

            for (int i = 0; i < 5; i++)
            {
                SaveWorkflowAsyncResult.AddSerializedProperty(properties[i], parameters, dataPropertyParameters[i]);
            }

            this.SerializePromotedProperties(parameters, commandTextBuilder, saveWorkflowCommand);
        }