# CFLOCK

The CFLOCK tag provides two types of locks to ensure the integrity of shared data:

- exclusive lock
- read-only lock

An exclusive lock single-threads access to the CFML constructs in its body. Single-threaded access implies that the body of the tag can be executed by at most one request at a time. A request executing inside a CFLOCK tag has an "exclusive lock" on the tag. No other requests are allowed to start executing inside the tag while a request has an exclusive lock. ColdFusion issues exclusive locks on a first-come, first-served basis.

A read-only lock allows multiple requests to access the CFML constructs inside its body concurrently. Therefore, read-only locks should only be used when the shared data will only be read and not modified. If another request already has an exclusive lock on the shared data, the request will wait for the exclusive lock to be released before it can obtain it.

### Syntax

    <CFLOCK
        TIMEOUT="timeout in seconds "
        SCOPE="Application" or "Server" or "Session"
        NAME="lockname"
        THROWONTIMEOUT="Yes/No"
        TYPE= "ReadOnly/Exclusive ">
        <!--- CFML to be synchronized --->
    </CFLOCK>

#### TIMEOUT

Required. Specifies the maximum amount of time in seconds to wait to obtain an lock. If a lock can be obtained within the specified period, execution will continue inside the body of the tag. Otherwise, the behavior depends on the value of the THROWONTIMEOUT attribute.

#### SCOPE

Optional. Specifies the scope as one of the following: Application, Server, or Session. This attribute is mutually exclusive with the NAME attribute. See the Scope section for valuable information.

#### NAME

Optional. Specifies the name of the lock. Only one request will be able to execute inside a CFLOCK tag with a given name. Therefore, providing the NAME attribute allows for synchronizing access to the same resources from different parts of an application. Lock names are global to a ColdFusion server. They are shared between applications and user sessions, but not across clustered servers. This attribute is mutually exclusive with the SCOPE attribute. Therefore, do not specify the SCOPE attribute and the NAME attribute in the same tag. Note that the value of NAME cannot be an empty string.

#### THROWONTIMEOUT

Optional. Yes or No. Specifies how timeout conditions should be handled. If the value is Yes an exception will be generated to provide notification of the timeout. If the value is No execution continues past the </CFLOCK> tag. Default is Yes.

#### TYPE

Optional. ReadOnly or Exclusive. Specifies the type of lock: read-only or exclusive. Default is Exclusive. A read-only lock allows more than one request to read shared data. An exclusive lock allows only one request to read or write to shared data. See the following Note.

Note | Limit the scope of code that updates shared data. Exclusive locks are required to ensure the integrity of these updates, but they have a significant impact on performance. Read-only locks are faster. If you have a performance-sensitive application, you should substitute read- only locks for exclusive locks wherever it is possible, for example, when reading shared data.

### Usage

ColdFusion Server is a multi-threaded web application server that can process multiple page requests at any given time. Use CFLOCK to guarantee that multiple concurrently executing requests do not manipulate shared data structures, files, or CFXs in an inconsistent manner. Note the following:

- Using CFLOCK around CFML constructs that modify shared data ensures that the modifications occur one after the other and not all at the same time.
- Using CFLOCK around file manipulation constructs can guarantee that file updates do not fail due to files being open for writing by other applications or ColdFusion tags.
- Using CFLOCK around CFX invocations can guarantee that CFXs that are not implemented in a thread-safe manner can be safely invoked by ColdFusion. This usually only applies to CFXs developed in C++ using the CFAPI. Any C++ CFX that maintains and manipulates shared (global) data structures will have to be made thread-safe to safely work with ColdFusion. However, writing thread-safe C++ CFXs requires advanced knowledge. A CFML custom tag wrapper can be used around the CFX to make its invocation thread-safe.

### Scope

Whenever you display, set, or update variables, in one of the shared scopes, use the SCOPE attribute to identify the scope as Server, Application or Session.

Within the ColdFusion Administrator, the Locking page, under the Server section, allows you to set different characteristics of the locking schema according to scope.The following table shows which features are available for Server, Application, and Session scope.

Features | Server | Application | Session
--- | --- | --- | ---
No automatic checking or locking | Yes | Yes | Yes
Full checking | Yes | Yes | Yes
Automatic read locking | Yes | Yes | Yes
Single Threaded Sessions |  |  | Yes

Each feature that you select has tradeoffs.

- No automatic checking or locking. If you select this button, no reads or writes are locked or checked for correct protection. You should select this only after you have run with full checking and know that there are no errors to handle and that all locking is handled programmatically. Selecting this button provides the fastest performance.
- Full checking. If you select this button, all unlocked accesses will be detected. You should select this when you are in debug mode. Selecting this button slows performance.
- Automatic read locking. If you select this button, all reads are locked and unlocked writes cause an error. Selecting this button also slows down performance considerably.
- Single-threaded sessions: If you select this button, the whole request has to finish before another request for the same session is processed. Selecting this button may have an effect on performance depending on the request pattern. For example, the total response time may increase if an application has multiple frames that can be refreshed at once, thus causing multiple requests to have to queue up and wait to be processed.

For an analysis of best practices with respect to locking, please refer to Administering ColdFusion Server.

### Deadlocks

CFLOCK uses kernel level synchronization objects that are released automatically upon timeout and/or abnormal termination of the thread that owns them. Therefore, ColdFusion will never deadlock for an infinite period of time while processing a CFLOCK tag. However, very large timeouts can block request threads for long periods of time and thus radically decrease throughput. Always use the minimum timeout value allowed.

Another cause of blocked request threads is inconsistent nesting of CFLOCK tags and inconsistent naming of locks. If you are nesting locks, you and everyone accessing the locked variables must consistently nest CFLOCK tags in the same order . If everyone accessing locked variables does not adhere to these conventions, a deadlock can occur. A deadlock is a state in which no request can execute the locked section of the page. Thus, all requests to the protected section of the page are blocked until there is a timeout. The following tables show two scenarios that cause deadlocks.

Deadlock Scenario with Two Users
User 1 | User 2
--- | ---
Locks the session scope . | Locks the application scope.
Deadlock: Tries to lock application scope, but application scope already is locked by User 2. | Deadlock: Tries to lock the session scope, but session scope already is locked by User 1.

Deadlock Scenario With One User
User 1
Locks the session scope with a read lock.
Attempts to lock the session scope with an exclusive lock.
Deadlock: Attempts to lock the session scope with an exclusive lock, but cannot because the scope is already locked for reading.

The following deadlock scenario could take place if you tried to nest a write lock after a read lock, as in the following code:

    <CFLOCK TIMEOUT="60" SCOPE="SESSION" TYPE="ReadOnly">
        ...............
        <CFLOCK TIMEOUT="60" SCOPE="SESSION" TYPE="Exclusive">
        .........
        </CFLOCK>
    </CFLOCK>

Once a deadlock occurs neither of the users can do anything to break the deadlock, because the execution of their requests is blocked until the deadlock can be resolved by a lock timeout.

In order to avoid a deadlock, you and all who need to nest locks should do so in a well-specified order and name the locks consistently. In particular, if you need to lock access to the server, application, and session scopes, you must do so in the following order.

1. Lock the session scope. In the CFLOCK tag, indicate the scope by specifying "SESSION" as the value of the SCOPE attribute.

2. Lock the application scope. In the CFLOCK tag, indicate scope by specifying "APPLICATION" as the value of the SCOPE attribute.

3. Lock the server scope. In the CFLOCK tag, indicate the scope by specifying "SERVER" as the value of the SCOPE attribute.

4. Unlock the server scope.

5. Unlock the application scope.

6. Unlock the session scope.

Note | You can take out any pair of lock/unlock steps if you do not need to lock a particular scope. For example, you can take out Steps 3 and 4 if you do not need to lock the server scope. Similar rules apply for named locks.

For complete usage information on CFLOCK, see Developing Web Applications with ColdFusion.

### Example

    <!-------------------------------------------------------------
        This example shows how CFLOCK can be used to guarantee the
        consistency of data updates to variables in the Application,
        Server, and Session scopes.
        You should copy the following code into an Application.cfm
        file in the snippets directory.
    --------------------------------------------------------------->
        <HTML>
        <HEAD>
            <TITLE>Define Session and Application Variables</TITLE>
        </HEAD>

        <BASEFONT FACE="Arial, Helvetica" SIZE=2>
        <BODY  bgcolor="#FFFFD5">

        <H3>CFAPPLICATION Example</H3>

        <P>CFAPPLICATION defines scoping for a ColdFusion application and
        enables or disables the storing of application and/or session
        variables. This tag is placed in a special file called
        Application.cfm that is run before any other CF template in a
        directory where the Application.cfm file appears.</P>

        <CFAPPLICATION NAME="ETurtle" SESSIONTIMEOUT=#CreateTimeSpan(0, 0,
          0, 60)# SESSIONMANAGEMENT="yes">

    <!----------------------------------------------------------------------
        Initialize the session and application variables that will be
        used by E-Turtleneck. Use the session scope for the session
        variables.
    ----------------------------------------------------------------------->
        <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>
    <!----------------------------------------------------------------------
        End of Application.cfm
    ------------------------------------------------------------------------
    >
    <HEAD>
    <TITLE>
    CFLOCK Example
    </TITLE>
    </HEAD>

    <BASEFONT FACE="Arial, Helvetica" SIZE=2>
    <BODY  bgcolor="#FFFFD5">

    <H3>CFLOCK Example</H3>

    <CFIF IsDefined("form.submit")>
        <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>.
        </CFOUTPUT>

        <!-----------------------------------------------------------------
         Lock session variables to assign form values to them.
        ------------------------------------------------------------------->
        <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.
        ------------------------------------------------------------------->
        <CFLOCK SCOPE="Application" TIMEOUT="30" TYPE="Exclusive">
            <CFSET application.number = application.number + 1>
        </CFLOCK>

    <CFELSE><!--- Show the form only if it has not been submitted. --->

    <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
    that you wish 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>XXsmall
            <OPTION>Xsmall
            <OPTION>small
            <OPTION>medium
            <OPTION>large
            <OPTION>Xlarge
            </SELECT>
        </td>
    </tr>
    <tr>
        <td>Press Submit when you are finished making your selection.</td>
        <td><INPUT TYPE="Submit" NAME="submit" VALUE="Submit">
        </td>
    </tr>
    </table>
    </FORM>
    </CFIF>
    </HTML>