Skip to main content
Participant
October 28, 2011
Question

Incrementing a variable in memory

  • October 28, 2011
  • 3 replies
  • 1715 views

I have an older application that is querying a list, pulling out an AD from the list, then incrementing the database by +1 with every pull. The site has grown very popular and now the traffic is creating a ton of deadlocks. I tried using CFLOCK but that made things worse.

Instead of writing each increment to the DB, I want to write it to memory and then run a routine which collects that value at some interval and update the DB.

How would I do this? Would I use an Array or some other method? I am not all that familiar with CF.  Thanks in advance.

This topic has been closed for replies.

3 replies

November 8, 2011

I researched this using a global application variable and that is exactly what I want to do. My problem now is I have no idea how to do that and generate a unique global variable each time since the variable company_id is always random.

Here is my existing code.

**This section queries my database for current advertisers**

<CFQUERY NAME="GRABCOMPANYINFO" DATASOURCE="bg4" cachedwithin="#CreateTimeSpan(0,0,30,0)#">

SELECT      COMPANY_ID, COMPANY, WEBADDRESS, graphic, flashad

FROM         dbo.COMPANIES

WHERE       (COMPANY_ID = #COMPANY_ID#)

</CFQUERY>

**Once it pulls the ad the below code updates the views in the DB.

<cflock name="bannerkingwrite" timeout="10" throwontimeout="no" type="readonly">

<CFQUERY NAME="UPDATEVIEWS" DATASOURCE="BG4">

UPDATE     dbo.BANNERKING

SET        VIEWS=VIEWS +1,MONTHVIEWS=MONTHVIEWS + 1

WHERE       COMPANY_ID = #COMPANY_ID#

</CFQUERY>

</cflock>

What I want to do is to replace the Update Query above with an application variable.  Any idea how I could do that? 

Thanks -

BKBK
Community Expert
Community Expert
November 8, 2011

<cflock scope="application" timeout="10" throwontimeout="no" type="exclusive">

<CFQUERY NAME="application.GRABCOMPANYINFO" DATASOURCE="bg4">

    SELECT      COMPANY_ID, COMPANY, WEBADDRESS, graphic, flashad

    FROM        dbo.COMPANIES

    WHERE       COMPANY_ID = #application.COMPANY_ID#

</CFQUERY>

    <CFQUERY NAME="UPDATEVIEWS" DATASOURCE="BG4">

    UPDATE     dbo.BANNERKING

    SET        VIEWS=VIEWS +1,MONTHVIEWS=MONTHVIEWS + 1

    WHERE      COMPANY_ID = #application.COMPANY_ID#

    </CFQUERY>

</cflock>

Participant
November 8, 2011

Thanks, but that is not what I was looking for.

The first query is fine, I would like to remove the second query which updates the views with an application variable. So it would increment the variable in memory and then I can write it out to the database later.

Something similar to this:

<cflock scope = "Application" timeout = "30" type = "Exclusive">

    <cfset application.views#company_id# = application.views#company_id# + 1>

    </cflock>

This does not seem to work.

BKBK
Community Expert
Community Expert
November 3, 2011

pjlefemine wrote:

I have an older application that is querying a list, pulling out an AD from the list, then incrementing the database by +1 with every pull. The site has grown very popular and now the traffic is creating a ton of deadlocks. I tried using CFLOCK but that made things worse.

Instead of writing each increment to the DB, I want to write it to memory and then run a routine which collects that value at some interval and update the DB.

How would I do this? Would I use an Array or some other method? I am not all that familiar with CF.  Thanks in advance.

A result-set is more or less equivalent to a 2-dimensional array. So you may use an array or a struct to store the data. If the variable involves a user's increment, make it a session variable. Then collect the values within an interval in an application variable, as Dan says.

Inspiring
October 28, 2011

An application variable might do the trick.

Inspiring
October 28, 2011

Are you doing your incrementing in the same SQL statement as your select or are you performing them as 2 separate queries?  If you are doing 2 database interactions, its probably a good idea to combine them into a multi-statement SQL block or a stored procedure.  Something like this:

<cfquery ...>

Update myADList

SET counter_field = counter_field + 1

WHERE id_field = 2;

SELECT *

FROM myADList

WHERE id_field = 2

</cfquery>

Or, alternatively, this seems like an excellent candidate for an asynchronous process.  Perhaps instead of having a counter field in your List table (which is giving you deadlock read/write problems), you created a new table that logged AD views.  You could capture a lot more details about your viewers (location/IP Address, datetime, etc) which would allow you to analyze your data a little more.  You could then fire the Log insert off as an asynchronous CF thread or an AJAX call.

Hope that helps

-Michael