Adobe ColdFusion 8

Sample locking scenarios

The following examples present scenarios in which you need to lock ColdFusion code. These scenarios show only two of the circumstances where locking is vital.

Reading and writing a shared variable

If you have an application-wide value, such as a counter of the total number of tickets sold, you might have code such as the following on a login page:

<cfset Application.totalTicketsSold = Application.totalTicketsSold + ticketOrder>

When ColdFusion executes this code, it performs the following operations:

  1. Retrieves the current value of Application.totalTicketsSold from temporary storage.
  2. Increments this value.
  3. Stores the result back in the Application scope.

Suppose that ColdFusion processes two ticket orders at approximately the same time, and that the value of Application.totalTicketsSold is initially 160. The following sequence might happen:

  1. Order 1 reads the total tickets sold as 160.
  2. Order 2 reads the total tickets sold as 160.
  3. Order 1 adds an order of 5 tickets to 160 to get 165.
  4. Order 2 adds an order of 3 tickets to 160 to get 163.
  5. Order 1 saves the value 165 to Application.totalTicketsSold
  6. Order 2 saves the value 163 to Application.totalTicketsSold

The application now has an inaccurate count of the tickets sold, and is in danger of selling more tickets than the auditorium can hold.

To prevent this from happening, lock the code that increments the counter, as follows:

<cflock scope="Application" timeout="10" type="Exclusive">
    <cfset Application.totalTicketsSold = Application.totalTicketsSold + ticketOrder>
</cflock>

The cflock tag ensures that while ColdFusion performs the processing in the tag body, no other threads can access the Application scope. As a result, the second transaction is not processed until the first one completes. The processing sequence looks something like the following:

  1. Order 1 reaches the lock tag, which gets an Application scope lock.
  2. Order 1 reads the total tickets sold as 160.
  3. Order 2 reaches the lock tag. Because there is an active Application scope lock, ColdFusion waits for the lock to free.
  4. Order 1 adds an order of 5 tickets to 160 to get 165.
  5. Order 1 saves the value 165 to Application.totalTicketsSold.
  6. Order 1 exits the lock tag. The Application scope lock is now free.
  7. Order 2 gets the Application scope lock and can begin processing.
  8. Order 2 reads the total tickets sold as 165.
  9. Order 2 adds an order of 3 tickets to 165 to get 168.
  10. Order 2 saves the value 168 to Application.totalTicketsSold.
  11. Order 2 exits the lock tag, which frees the Application scope lock. ColdFusion can process another order.

The resulting Application.totalTickesSold value is now correct.

Ensuring consistency of multiple variables

Often an application sets multiple shared scope variables at one time, such as a number of values submitted by a user on a form. If the user submits the form, clicks the back button, and then resubmits the form with different data, the application might end up with a mixture of data from the two submissions, in much the same manner as shown in the previous section.

For example, an application might store information about order items in a Session scope shopping cart. If the user submits an item selection page with data specifying sage green size 36 shorts, and then resubmits the item specifying sea blue size 34 shorts, the application might end up with a mixture of information from the two orders, such as sage green size 34 shorts.

By putting the code that sets all of the related session variables in a single cflock tag, you ensure that all the variables get set together. In other words, setting all of the variables becomes an atomic, or single, operation. It is similar to a database transaction, where everything in the transaction happens, or nothing happens. In this example, the order details for the first order all get set, and then they are replaced with the details from the second order.

For more examples of using locking in applications, see Examples of cflock.