Upgrading SharePoint
workflow is simple, run stsadm- upgradesolution command like any other solution
in SharePoint. However you need to know that it can affect existing in progress
workflows. I learned it the hard way. Here is what happened, I developed a workflow
using Visual Studio and deployed to production after testing. Now after a few
weeks I was asked to fix some bugs and add some minor functionality to it. I
did that in a few hours, tested and then deployed to production. All the newly
created workflows worked fine but “some” of the in progress workflows’ tasks
started throwing out “This task is curently locked by a runnign workflow and
cannot be edited”. Googling this error pointed to some interesting articles on
what causes it. From what i read the root cause is that the SPListItem[SPBuiltInFieldId.WorkflowVersion]!=1,
this article seems to solve it by programmatically making it equal to 1 as can
be seen here:
http://geek.hubkey.com/2007/09/locked-workflow.html
http://geek.hubkey.com/2007/09/locked-workflow.html
I tried it but it didnt
work for me, although the WorkflowVersion was equal to 1 after running the code
mentioned.
Googled more and came
across this article which explained it a bit more :
http://blogs.code-counsel.net/Wouter/Lists/Posts/Post.aspx?List=c04a88a9%2Dd138%2D4ac3%2Da2bb%2Db95c9fdd114e&ID=118
http://blogs.code-counsel.net/Wouter/Lists/Posts/Post.aspx?List=c04a88a9%2Dd138%2D4ac3%2Da2bb%2Db95c9fdd114e&ID=118
Similar articles on this
topic leads me to believe that this error is caused by de-serialization of a
workflow that has been saved in the database. Since this in progress workflow
was created by the older dll/code which is serialized when hydarting the
workflow, when the user tries to update the task it deserializes this workflow
but since the code has been updated its not able to do it and hence think the
current action is not perfomed by the workflow that serialized this orginally.
So if you want to update workflows
in the future you have the following options:
1. Terminate in progress workflows and start again
2. Let in progress workflows to complete before upgrading solution
3. Version your workflows manually by changing the GUID and changing its name , lets say “_v2″ etc. So basically making a new workflow with a different name and attach to the list. Also making sure that the existing workflow is allowed to complete which can be done by going to “List Settings”->Workflow Settings->”Allow New Instances” set to “No”. I see something similar used by Nintex if you ever update the workflow from GUI you will versions of workflow automatically set to not allow new instances of pervious workflows.
1. Terminate in progress workflows and start again
2. Let in progress workflows to complete before upgrading solution
3. Version your workflows manually by changing the GUID and changing its name , lets say “_v2″ etc. So basically making a new workflow with a different name and attach to the list. Also making sure that the existing workflow is allowed to complete which can be done by going to “List Settings”->Workflow Settings->”Allow New Instances” set to “No”. I see something similar used by Nintex if you ever update the workflow from GUI you will versions of workflow automatically set to not allow new instances of pervious workflows.
Issue and Solution for Custom Wrokflows
Root cause: issue has occurred whenever a task has been altered. If
a workflow is ‘waiting’ for an event from this task, it will
be ‘locked’ and unchangeable until the workflow has a change
to process this event.
Solution (work-around 1): Using the
below code snippet you can find out the workflow status and
can do the necessary action.
SPWorkflowCollection wfs = item.Workflows;
foreach(SPWorkflow
wf in wfs)
{
if ( wf.InternalState.ToString() != "Locked, Running")
{
// alter the task here
}
}
{
if ( wf.InternalState.ToString() != "Locked, Running")
{
// alter the task here
}
}
If we are trying to change the status of workflow
from outside the workflow this error will throw, In this
case I had used a custom aspx page to do that. So, in order to avoid that
locking exception, before changing the status find out the status of the
workflow whether it is locked status or not and make the changes.
Solution (work-around 2):
Make the alteration task not synchronous and make the NonSerialaized SP objects
If we use some objects like
SPWeb,SPUser, it has to be NonSerializable. So we have to make those type of
objects in the SharePoint workflow code as NonSerializable by adding the
[NonSerialaized()] attribute on top of the declarations.
Eg:if you are using a SPWeb and SPUser
as like this
private SPWeb oWeb = null;
private SPUser oUser = null;
then you can make those objects as
NonSerialized like below,
[NonSerialized()]
private SPWeb oWeb = null;
[NonSerialized()]
private SPUser oUser = null;
Also, one more important change you have
to make is synchronization = false while altering the task.
if we alter the task like this SPWorkflowTask.AlterTask(oTaskListItem, oTaskHash, true);, the third parameter represents a Boolean variable
denotes synchronization is true or false. If we make it as true, it will make
immediate modification on task (it mightcreate this locking issue) and if make
it as false then it will depend on the timer activity and later it will be
modified.
So if we get this error message, make
the synchronization parameter as false. like below
SPWorkflowTask.AlterTask(oTaskListItem, oTaskHash, false);
No comments:
Post a Comment