<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: What&#8217;s the Best Way to Manage a Database Queue?</title>
	<atom:link href="http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/feed/" rel="self" type="application/rss+xml" />
	<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/</link>
	<description></description>
	<lastBuildDate>Wed, 08 Feb 2012 05:13:13 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: Daniel</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-216371</link>
		<dc:creator>Daniel</dc:creator>
		<pubDate>Wed, 03 Mar 2010 19:11:22 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-216371</guid>
		<description>Thank you,

So you did your polling based on a timer? and added more services if need be? how would you know if you needed to add more by the difference between locktime and Requested time?</description>
		<content:encoded><![CDATA[<p>Thank you,</p>
<p>So you did your polling based on a timer? and added more services if need be? how would you know if you needed to add more by the difference between locktime and Requested time?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Griswold</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-215445</link>
		<dc:creator>Ben Griswold</dc:creator>
		<pubDate>Wed, 03 Feb 2010 21:39:50 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-215445</guid>
		<description>Hi Daniel,

If I am understanding your question correctly, I didn&#039;t do any special processing. There was no multi-thread or throttling. The service(s) merely polled the queue on a given timer interval.  If items were in the queue, each service would process queued items until all were processed to completion. Once all items were processed, each service would wait until the next interval fired and the polling and processing continued.

I hope this helps,
Ben</description>
		<content:encoded><![CDATA[<p>Hi Daniel,</p>
<p>If I am understanding your question correctly, I didn&#8217;t do any special processing. There was no multi-thread or throttling. The service(s) merely polled the queue on a given timer interval.  If items were in the queue, each service would process queued items until all were processed to completion. Once all items were processed, each service would wait until the next interval fired and the polling and processing continued.</p>
<p>I hope this helps,<br />
Ben</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-215016</link>
		<dc:creator>Daniel</dc:creator>
		<pubDate>Mon, 25 Jan 2010 23:22:30 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-215016</guid>
		<description>How do you throttle the windows service to handle more loads?</description>
		<content:encoded><![CDATA[<p>How do you throttle the windows service to handle more loads?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Griswold</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-197115</link>
		<dc:creator>Ben Griswold</dc:creator>
		<pubDate>Mon, 25 May 2009 14:19:05 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-197115</guid>
		<description>@Giorgio - You&#039;re first case is covered using the @MinutesBeforeBreakLock variable. @MinutesBeforeBreakLock gives a thread a limited amount of time to complete the processing the queued item. 

If, after the number of minutes established with @MinutesBeforeBreakLock, row processing isn&#039;t completed, the row becomes available for processing by another thread.  This logic was put in place for exactly the reason you mentioned -- failures dues external issues.

Regarding your second case, that&#039;s not built into the script right now, but it could be extended pretty easily. Off the top of my head (read: following queries should be vetted), a &quot;NumAttempts&quot; column could be added to the Queue table and incremented each time a given row is &quot;pulled off&quot; the queue as part of the update:

update Queue
set    LockedBy = @LockedBy,
    LockedTime = GetDate(),
    NumAttempts = Coalesce(NumAttempts,0) + 1
where RequestId = @RequestId 


If you want to limit the number of attempts, the select statement would be changed to something like this:

select top 1 @RequestId = RequestId
from Queue with (updlock)
where Status = @PendingStatus
and (LockedTime IS NULL OR
DateDiff(mi, LockedTime, GetDate()) &gt;= @MinutesBeforeBreakLock)
and (NumAttempts &lt; @AttemptsAllowed)
order by RequestedTime Asc 

Note, the restriction based on NumAttempts being less than your established limit.  

Thanks for the comment and the question.</description>
		<content:encoded><![CDATA[<p>@Giorgio &#8211; You&#8217;re first case is covered using the @MinutesBeforeBreakLock variable. @MinutesBeforeBreakLock gives a thread a limited amount of time to complete the processing the queued item. </p>
<p>If, after the number of minutes established with @MinutesBeforeBreakLock, row processing isn&#8217;t completed, the row becomes available for processing by another thread.  This logic was put in place for exactly the reason you mentioned &#8212; failures dues external issues.</p>
<p>Regarding your second case, that&#8217;s not built into the script right now, but it could be extended pretty easily. Off the top of my head (read: following queries should be vetted), a &#8220;NumAttempts&#8221; column could be added to the Queue table and incremented each time a given row is &#8220;pulled off&#8221; the queue as part of the update:</p>
<p>update Queue<br />
set    LockedBy = @LockedBy,<br />
    LockedTime = GetDate(),<br />
    NumAttempts = Coalesce(NumAttempts,0) + 1<br />
where RequestId = @RequestId </p>
<p>If you want to limit the number of attempts, the select statement would be changed to something like this:</p>
<p>select top 1 @RequestId = RequestId<br />
from Queue with (updlock)<br />
where Status = @PendingStatus<br />
and (LockedTime IS NULL OR<br />
DateDiff(mi, LockedTime, GetDate()) &gt;= @MinutesBeforeBreakLock)<br />
and (NumAttempts &lt; @AttemptsAllowed)<br />
order by RequestedTime Asc </p>
<p>Note, the restriction based on NumAttempts being less than your established limit.  </p>
<p>Thanks for the comment and the question.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Giorgio Bozio</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-197076</link>
		<dc:creator>Giorgio Bozio</dc:creator>
		<pubDate>Mon, 25 May 2009 08:05:06 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-197076</guid>
		<description>Hi,
very nice implementation!

what about if I need to re queue an item if processing encountered some external problem? 

And what if I want to retry processing for a limited number of times, after which i drop the queue item.</description>
		<content:encoded><![CDATA[<p>Hi,<br />
very nice implementation!</p>
<p>what about if I need to re queue an item if processing encountered some external problem? </p>
<p>And what if I want to retry processing for a limited number of times, after which i drop the queue item.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Campbell</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-193143</link>
		<dc:creator>Joe Campbell</dc:creator>
		<pubDate>Wed, 29 Apr 2009 15:35:39 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-193143</guid>
		<description>Yes u did. Thank you.</description>
		<content:encoded><![CDATA[<p>Yes u did. Thank you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Griswold</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-192764</link>
		<dc:creator>Ben Griswold</dc:creator>
		<pubDate>Tue, 28 Apr 2009 03:16:22 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-192764</guid>
		<description>@Joe - That&#039;s where the update lock (or updlock) comes in. 

Let&#039;s say Request A and B come in at exactly the same time. Well, SQL Server will ensure that only one of the requests will get a lock on the top row - in other words, the next row to be processed in the queue. 

Once a row is locked, it is no longer available and it can&#039;t be locked by another request. It should also be noted that the lock stays in place until the associated update is performed. 

If Request A gets the initial lock, Request B will lock the next row in the queue and follow the same process as Request A (lock row and capture id, update row based on LockedBy and LockedTime values, implicitly release lock.)

Did I answer your question?</description>
		<content:encoded><![CDATA[<p>@Joe &#8211; That&#8217;s where the update lock (or updlock) comes in. </p>
<p>Let&#8217;s say Request A and B come in at exactly the same time. Well, SQL Server will ensure that only one of the requests will get a lock on the top row &#8211; in other words, the next row to be processed in the queue. </p>
<p>Once a row is locked, it is no longer available and it can&#8217;t be locked by another request. It should also be noted that the lock stays in place until the associated update is performed. </p>
<p>If Request A gets the initial lock, Request B will lock the next row in the queue and follow the same process as Request A (lock row and capture id, update row based on LockedBy and LockedTime values, implicitly release lock.)</p>
<p>Did I answer your question?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Campbell</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-192754</link>
		<dc:creator>Joe Campbell</dc:creator>
		<pubDate>Tue, 28 Apr 2009 02:22:17 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-192754</guid>
		<description>Ben, thanks for the quick response. How does this handle concurrent client requests for a row which is not locked?</description>
		<content:encoded><![CDATA[<p>Ben, thanks for the quick response. How does this handle concurrent client requests for a row which is not locked?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Griswold</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-192688</link>
		<dc:creator>Ben Griswold</dc:creator>
		<pubDate>Mon, 27 Apr 2009 22:52:00 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-192688</guid>
		<description>@Joe Campbell - It does. As a matter of fact, that&#039;s the primary reason for a routine like this. When a row is locked, it is timestamped and who locked it is captured. As long as the row is locked and the expiration time isn&#039;t met, the row won&#039;t be processed again - by any client. Thanks for asking.</description>
		<content:encoded><![CDATA[<p>@Joe Campbell &#8211; It does. As a matter of fact, that&#8217;s the primary reason for a routine like this. When a row is locked, it is timestamped and who locked it is captured. As long as the row is locked and the expiration time isn&#8217;t met, the row won&#8217;t be processed again &#8211; by any client. Thanks for asking.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Campbell</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-192676</link>
		<dc:creator>Joe Campbell</dc:creator>
		<pubDate>Mon, 27 Apr 2009 22:22:09 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-192676</guid>
		<description>does this scale in a web cluster environment making sure one request is not processed by two clients?</description>
		<content:encoded><![CDATA[<p>does this scale in a web cluster environment making sure one request is not processed by two clients?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Griswold</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-145502</link>
		<dc:creator>Ben Griswold</dc:creator>
		<pubDate>Tue, 11 Nov 2008 16:36:15 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-145502</guid>
		<description>Hi TG.  The implementation outlined above has been running in production for well over a year now without issues. We haven&#039;t encountered any issues yet.  Thanks for following up.</description>
		<content:encoded><![CDATA[<p>Hi TG.  The implementation outlined above has been running in production for well over a year now without issues. We haven&#8217;t encountered any issues yet.  Thanks for following up.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: TG</title>
		<link>http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/comment-page-1/#comment-145434</link>
		<dc:creator>TG</dc:creator>
		<pubDate>Tue, 11 Nov 2008 10:56:22 +0000</pubDate>
		<guid isPermaLink="false">http://johnnycoder.com/blog/2007/06/20/whats-the-best-way-to-manage-a-database-queue/#comment-145434</guid>
		<description>did u face any problems with this one? I am trying to do exactly same and wondering if this works fine or needs some improvement :)</description>
		<content:encoded><![CDATA[<p>did u face any problems with this one? I am trying to do exactly same and wondering if this works fine or needs some improvement <img src='http://johnnycoder.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
</channel>
</rss>

