Using locks in Custom MOSS Timer Jobs
The class containing the invocation code for the timer jobs must inherit from the Microsoft.SharePoint.Administration.SPJobDefinition class. The constructors need to be created and the Execute() method must be overridden as mentioned below. The Execute() method is overridden for performing the custom activity that the user has planned to do using the timer jobs. The Execute() is invoked by the MOSS timer services but if there is no lock applied on the code then concurrency issues arise if different users are planning to trigger the timer job at the same time. To overcome concurrency issues the Execute() code must be locked by the process that is executing and the other concurrent process must wait till the lock is removed.
Scenario: Users in an organization are planning to synchronize lists(which they have access on) in a MOSS web application. They are performing the activity by using a UI (ASP.Net web application running under MOSS context) and creating timer jobs that in turn run and complete the process. Users who are requesting for the sync activity are notified with a mail in the end on the success or failure of the job. In our current scenario we are planning to use the included property bag (SPJobDefinintion.Properties) to store your custom properties. The property bag stores the requestor alias(UserAlias) and the SiteUrl. namespace Infosys.Blogs{public class TimerJobClass : SPJobDefinition
{
/// <summary>
/// Base class constructor
/// </summary>
public TimerJobClass() : base()
{
}
public TimerJobClass(string jobName, SPService service, SPServer server, SPJobLockType targetType) : base (jobName, service, server, targetType)
{
} /// <summary>
/// Constructor that accepts the JobName,SPWebapplication
/// </summary>
public TimerJobClass(string jobName, SPWebApplication webApplication)
: base (jobName, webApplication, null, SPJobLockType.ContentDatabase)
{
}
/// <summary>
/// Called by MOSS when the Job is kicked off for execution
/// </summary>
/// <param name="contentDbId"></param>
public override void Execute(Guid contentDbId)
{
lock (timerLock)
{
//Fetch the value from the Job PropertyBag
if (this.Properties.ContainsKey(JobPBValue))
{
fetchJobPB = this.Properties[timerJobName].ToString();
} string[] jobPropertyBag = fetchJobPB.Split(',');
string siteUrl = jobPropertyBag[jobPropertyBag.Length - 0];
string userAlias = jobPropertyBag[jobPropertyBag.Length - 1];
//Queue at the Root site collection level of the web application
currentSite = new SPSite(siteUrl);
currentSite = new SPSite(currentSite.Url);
currentWeb = currentSite.OpenWeb(); //Body of code - writes to a list
..
//End of code - writes to a list
SPUtility.SendEmail(currentWeb, false, false, userAlias, "Status of Timer Job" + this.Name, “The Job is Completed”);
}


Comments
Good post.
Posted by: Senthamil | February 17, 2009 03:12 PM
I have created one timer job that sends reminder emails for over due tasks. I am all done with activating the timer job as a site collection feature. but the problem is when the feature is activated, the Execute() method is not getting fired. What could be the reason for this?
Thanks,
Sudheer
Posted by: Sudheer | January 28, 2010 04:28 PM