The following examples show how to use CFLOCK in a variety of situations.
This example shows how CFLOCK can be used to guarantee the consistency of data updates to variables in the Application, Server, and Session scopes.
The following sample code might be part of the Application.cfm
file.
<HTML>
<HEAD>
<TITLE>Define Session and Application Variables</TITLE>
</HEAD>
<H3>CFAPPLICATION Example</H3>
<P>CFAPPLICATION defines scoping for a
ColdFusion applicationand enables or disables
the storing of client and/or session variables.
This tag is placed in the Application.cfm file
for the current application.
<CFAPPLICATION NAME="ETurtle"
SESSIONTIMEOUT=CreateTimeSpan("60")
SESSIONMANAGEMENT="yes">
<!--- Initialize the session and application
variables that will be used by E-Turtleneck. Use
the session lock for the session variables.
The member variable sessionID creates the
session name for you. --->
<CFLOCK SCOPE="Session"
TIMEOUT="30" TYPE ="Exclusive">
<CFIF NOT IsDefined("session.size")>
<CFSET session.size = "">
</CFIF>
<CFIF NOT IsDefined("session.color")>
<CFSET session.color = "">
</CFIF>
</CFLOCK>
<!--- Use the application lock for the
application variable. This variable keeps
track of the total number of turtlenecks sold.
The application lock should have the same name
as specified in the CFAPPLICATION tag. --->
<CFLOCK Scope="Application"
TIMEOUT="30"
TYPE="Exclusive">
<CFIF NOT IsDefined("application.number")>
<CFSET application.number = 1>
</CFIF>
</CFLOCK>
<CFLOCK SCOPE="Application"
TIMEOUT="30"
TYPE ="ReadOnly">
<CFOUTPUT>
E-Turtleneck is proud to say that we have sold
#application.number# turtlenecks to date.
</CFOUTPUT>
</CFLOCK>
Tip | In general, you should limit lock scopes. When locking variables, queries, and arrays (anything other than structures), you can copy to a local variable in the CFLOCK block, then reference the local variable. |
The remaining sample code would appear inside the application page where customers place orders.
<HTML> <HEAD> <TITLE>CFLOCK Example</TITLE> </HEAD> <BODY> <H3>CFLOCK Example</H3> <CFIF IsDefined("form.submit")> <!--- Lock session variables ---> <CFLOCK SCOPE="Session" TIMEOUT="30" TYPE="ReadOnly"> <CFOUTPUT>Thank you for shopping E-Turtleneck. Today you have chosen a turtleneck in size <B>#form.size#</B> and in the color <B>#form.color#</B>. Your order number is #session.sessionID#. </CFOUTPUT> </CFLOCK> <!--- Lock session variables to assign form values to them. To lock session variables, you should get the session ID with the sessionID member variable. ---> <CFLOCK SCOPE="Session" TIMEOUT="30" TYPE="Exclusive"> <CFPARAM Name=session.size Default=#form.size#> <CFPARAM Name=session.color Default=#form.color#> </CFLOCK> <!--- Lock application variable application.number to find the total number of turtlenecks sold. If you don't know the name of the application, you can use the member variable applicationName to find it.---> <CFLOCK SCOPE="Application" TIMEOUT="30" TYPE="Exclusive"> <CFSET application.number=application.number + 1> </CFLOCK> <!--- Show the form only if it has not been submitted. ---> <CFELSE> <FORM ACTION="cflock.cfm" METHOD="Post"> <P> Congratulations! You have just selected the longest wearing, most comfortable turtleneck in the world. Please indicate the color and size you want to buy.</P> <TABLE CELLSPACING="2" CELLPADDING="2" BORDER="0"> <TR> <TD>Select a color.</TD> <TD><SELECT TYPE="Text" NAME="color"> <OPTION>red <OPTION>white <OPTION>blue <OPTION>turquoise <OPTION>black <OPTION>forest green </SELECT> </TD> </TR> <TR> <TD>Select a size.</TD> <TD><SELECT TYPE="Text" NAME="size"> <OPTION>small <OPTION>medium <OPTION>large <OPTION>xlarge </SELECT> </TD> </TR> <TR> <TD></TD> <TD><INPUT TYPE="Submit" NAME="submit" VALUE="Submit"> </TD> </TR> </TABLE> </FORM> </CFIF> </BODY> </HTML>
The following example demonstrates how to use CFLOCK to synchronize access to a file system. The CFLOCK tag protects a CFFILE tag from attempting to append data to a file already open for writing by the same tag executing on another request.
Note that if an append operation takes more that one minute, a request waiting to obtain an exclusive lock to the critical section may time out. Also, note the use of a dynamic value for the NAME attribute to allow protection of a file with any given name.
<CFLOCK NAME=#FileName# TIMEOUT=60 TYPE="Exclusive">
<CFFILE ACTION="Append"
FILE=#FileName#
OUTPUT=#TextToAppend#>
</CFLOCK>
This example illustrates how a custom tag wrapper can be built around CFXs that are not thread-safe. The wrapper simply forwards attributes to the non thread-safe CFX that is used inside a CFLOCK tag. An anonymous lock is used here because this is the only place from which the CFX will be invoked.
<CFPARAM NAME="Attributes.AttributeOne" Default="">
<CFPARAM NAME="Attributes.AttributeTwo" Default="">
<CFPARAM NAME="Attributes.AttributeThree" Default="">
<CFLOCK TIMEOUT=10 TYPE="Exclusive">
<CFX_NOT_THREAD_SAFE AttributeOne=#Attributes.AttributeOne#
AttributeTwo=#Attributes.AttributeTwo#
AttributeThree=#Attributes.AttributeThree#>
</CFLOCK>
Note | This example assumes that this is the only instance this CFX is used in the application. To lock a non-thread safe CFX that used multiple times in an application, used named locking rather than anonymous locking, specifying the same name for each lock. |
See the CFML Language Reference for more information on using CFLOCK.