This Task Is Currently Locked by a Running Workflow and Cannot Be Edited

 

Problem: In SharePoint Workflow, "This task is currently locked by a running workflow and cannot be edited" is the common exception, that we face.

Solution:
Generally this exception occurs
1.  when the number of items in the Task List gets high

This exception says that the workflow is not able to deliver the all the events at a given time and so the tasks get locked. 
Out Of Box, the default event delivery throttle value is 15. 
Event delivery throttle value Specifies the number of workflows that can be processed at the same time across all front-end Web servers

look at following link.
(http://blogs.msdn.com/b/vincent_runge/archive/2008/09/16/about-the-workflow-eventdelivery-throttle-parameter.aspx )

If the value returned by query is superior to the throttle (15 by default), any new workflow event will not be processed immediately.

so we need to change it by stsadm command like...
stsadm -o setproperty -pn workflow-eventdelivery-throttle -pv "20"
(http://technet.microsoft.com/en-us/library/cc287939(office.12).aspx )

2. When we modify a Workflow Task from Custom TaskEdit Page.
 
when we try to modify the workflow task from outside workflow default Page, like custom workflow taskedit page. then is exception occurs.
suppose we have custom task edit page with dropdown  and values are submitted/ Progress/ completed etc and we want to complete task from here.
 
it will throw exception on SPWorkflowTask.AlterTask method, which changes the TaskStatus.
When I debug, to find the root cause I actully found that the workflow is not locked.

The InternalState flag of the workflow does not include the Locked flag bits
(http://msdn.microsoft.com/en-us/library/dd928318(v=office.12).aspx )
 
When I found this link http://geek.hubkey.com/2007/09/locked-workflow.html
It is exactly what I wanted. It says that "when the WorkflowVersion of the task list item is not equal to 1" then the error occurs. The solution that is propsed here works fantastically

if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)
{
    SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task[SPBuiltInFieldId.WorkflowListId].ToString())];
    SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);
    SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
    if (!workflow.IsLocked)
    {
       task[SPBuiltInFieldId.WorkflowVersion] = 1;
       task.SystemUpdate();
      break;
    }
}


 

It will reset the workflow version to 1 again.

Conclusion: This Exception is completely confusing. So, we need to find at first whether our workflow is really locked or not. If it is really locked then use 1st method. If not, then check the workflow version and set it to 1 again.

 
 
Understanding and resolving the workflow task locking issue

[Edit; seems like VTS attributes are not picked up as I expected]

A not so uncommon error that people encounter with SharePoint workflow is running into locked tasks. You know, the error that you get when working with workflow tasks, usually on your developer machine. You might get the error message "This task is currently locked by a running workflow and cannot be edited.".

Why do I know it is not uncommon? Well, if you use my common-o-meter you'll see for yourself:

That is a lot of hits!

So many people have this issue with task locking. Generally it goes like this. A developer creates a workflow that issues a couple of tasks. Next the developer fiddles with his code to get it right. Then, returning to his test workflow, he finds that when editing a task and clicking Ok, the SharePoint UI informs him of the fact that the task is locked and cannot be edited.

So, what is going on here? There are a number of items that show up searches for this error message, but never a good explanation on why you got there in the first place. More symptom management that bug fixing! Well, the first thing to note is that the error is absolutely correct. The task is locked, but why is it locked, and was it not unlocked appropriately? Despite what many people think this has nothing to do with your DLL versions, at least not as directly as you might find written and guessed at. Here's the story.

How workflow tasks are locked

The first thing to realize is that when SharePoint workflows alter tasks there needs to be some sort of locking behavior on tasks so that you will not accidentally create race conditions and update a task simultaneously, the one update overwriting the other. Typically database level locks are used but for SharePoint Workflow tasks however a more simple, business-layer type lock suffices. Since SharePoint workflow is about humans and not about maximum near real-time performance the chance of collisions is low enough not to be worried about this. The workflow runtime in SharePoint locks tasks by setting a field and persisting that to the database. It then checks on the field value to determine whether it is locked. You can actually see the code that does this. The SPWinOEItemEventReceiver implements the ItemUpdating and ItemUpdated events. In the ItemUpdating you can find code similar to the following pseudo code

if WorkflowVersion for item not equal to 1
throw locked error
else
Place lock (Set WorkflowVersion on item to value not equal to 1)

How the lock placement is actually implemented is that the WorkflowVersion is set to the value in _UIVersion, which contains a value indicating the major / minor version of the task. Why _UIVersion? It ties the lock to a specific version of the list item, and versioning is enabled on workflow task lists. This probably allows the locks to be bypassed by other code inside SharePoint depending on the version. (By the way: do *not* use this knowledge of internals in production code)

The next interesting question is where the lock is released. The ItemUpdated event facilitates this. When the task lock is detected in the ItemUpdated event it is routed to the SPWorkflowManager. This manager runs code to dehydrate and startup the workflow (which was persisted to the database while waiting for the task change to occur). The SPWorkflowManager uses the SPWinOeHostServices workflow service to unlock the task in the PostWorkItemDequeue method and runs the workflow.

Running into the locking issue

So, the issue is that the lock is still there even though it should have been released in the ItemUpdated event. Clearly, the ItemUpdated event is where the issue lies, and like all bugs in life, you did it, and not the framework! (hope that does not come as a shocker to you) There is only one aspect of the locking that you can control, and that is the persistence and hydration of your workflow to and from the database. This is exactly what is causing the bugs. When the ItemUpdated event fires and tries to de-serialize your workflow there might be an exception during the hydration of your workflow object. This error is difficult to see since it is happening in non-user code based on an asynchronous event. When that error occurs, the task unlocking code does not run! 

The general flow of events to create this issue goes something like this.

  • Developer designs a workflow which creates a task.
  • Developer tests the workflow, and runs it up to the task change activity, meaning that the workflow is now serialized in the database waiting for a task change to occur.
  • Developer spots a bug, and updates the workflow in such a way that de-serialization breaks.
  • Developer updates the task through the browser to continue the workflow .
  • Runtime bumps into the de-serialization error, and cannot continue, hence the task unlocking code does not run, and the task is locked for all eternity.

A common de-serialization issue that you might create is a change in the activity structure, or the addition of control fields in your main workflow class.  

Preventing the locking issue

Now that we have a clear understanding of the issue, there are many things you can about it. On development I'd go for re-running the entire workflow (at least when it is not too big).

On Production, it is even easier:

DO NOT UPGRADE UNTIL ALL RUNNING WORKFLOWS ARE COMPLETE

You should quiesce a workflow and when all running workflows have completed, update. Or, when you need to have the business logic available during the quiescing, you can only create a new workflow.

Hope it helps!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值