Locking Shared Variable Access


Before entering a discussion of the variables that are used to maintain session state, let's first discuss a concept that too many developers have ignored in past versions of ColdFusion. The concept is that of locking access to shared memory variables.

When we say "shared memory variables," we are referring to application-, session-, and server-scoped variables. These variables are stored as structures in the memory of the ColdFusion Server. Because ColdFusion is a multi-threaded application server, these memory structures can be subject to multiple simultaneous requests.

These simultaneous requests access the memory structures to read the variable values or to write new values to them. When a new value is written to the memory structure, the structure might change and any other request to the same variable might experience problems. These errors might lead to memory corruption or to crashes in certain ColdFusion processes.

Memory corruption can lead to memory leaks and server instability. Watch out for the following if you suspect memory corruption in your ColdFusion Server:

  • ColdFusion P-code errors

  • ColdFusion Server crashes

  • Unexpected variable evaluation

  • Runaway ColdFusion process memory

  • General operating system (OS) instability

ColdFusion gives us a method of locking access to these variables for a period of time. In effect, it enables us to single-thread-access certain variables for the purpose of reading the variable values or writing new ones.

Using CFLOCK

ColdFusion enables us to wrap references to shared scope variables with a call to the CFLOCK tag. The CFLOCK tag enables us to specify whether any of the shared scope variable values will be evaluated or written to.

The basic format of the CFLOCK call looks like this:

 <cflock scope="scope" type="type" timeout="seconds"> 

Table 8.1 provides a description of the attributes used in the call.

Table 8.1. CFLOCK Call Attributes

Attribute

Explanation

scope

Specifies whether the scope of the variable to be locked is of the application, session, or server scope.

type

readonly is used when you are reading variable values. exclusive is used when you are setting variable values.

timeout

Number of seconds to hold the lock.

The CFLOCK tag requires an end tag. The code that you want to lock access to should be encapsulated by the CFLOCK tag call:

 <cflock scope="session" type="readonly" timeout="10">           <cfset variables.CurrentUser=session.CurrentUser>  </cflock> 

Many developers are unsure of when to lock their code with a CFLOCK call. ColdFusion documentation tells us that we should use a CFLOCK tag in the following circumstances:

  • Using CFLOCK around ColdFusion Markup Language (CFML) constructs that modify shared data ensures that the modifications occur sequentially, not concurrently.

  • 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 CFAPI. A C++ CFX that maintains and manipulates shared (global) data structures must be made thread-safe to safely work with ColdFusion. However, writing thread-safe C++ CFXs requires advanced knowledge.

In the preceding example, we can see that the CFLOCK call wraps totally around the evaluation of the session.currentuser variable. It is more efficient to use a piece of code like this to reset the scope of the currentuser variable from session to local scope to avoid the necessity of coding CFLOCK tags every time the variable is accessed.

The scope attribute enables us to specify the variable scope to which our variable belongs. As seen in Table 8.1, the three variable scopes stored in memory are application, server, and session. When you set a lock on a variable, do not mix in variables of a different scope. This can cause errors to occur.

 <cflock scope="application" type="readonly" timeout="10">        <cfset variables.dsn=application.dsn>         <cfset session.sessionuser=form.userid>  </cflock> 

In the previous example, you can see that we are evaluating an application-scoped variable with a read-only lock; that's okay, but throwing in the set on the value of the session variable causes the code to throw an error. The best way to accomplish both operations is as follows:

 <cflock scope="application" type="readonly" timeout="10">      <cfset variables.dsn=application.dsn>  </cflock>  <cflock scope="session" type="exclusive" timeout="10">      <cfset session.sessionuser=form.userid>  </cflock> 

The two main variations on the CFLOCK tag deal with the type of lock that is created. Those variations of the type attribute are as follows:

  • Exclusive. Single threads access the memory location of a variable for the purpose of setting the value of that variable.

  • ReadOnly. Keeps the variable from having an exclusive lock established while enabling concurrent read access to the variable. If a user tries to establish an exclusive lock, he or she must wait for all read-only locks to expire.

As seen in Table 8.1, an exclusive lock is used for setting the value of variables. Now, let's take a look at each variation of CFLOCK:

  • Application scope

     <cflock scope="application" type="readonly" timeout="10">      <cfset variables.dsn=application.dsn>  </cflock>  <cflock scope="application" type="exclusive" timeout="10">     <cfset application.dsn="insidecoldfusionmx_data">  </cflock>  
  • Session scope

     <cflock scope="session" type="readonly" timeout="10">      <cfset variables.userid=session.userid>  </cflock>  <cflock scope="session" type="exclusive" timeout="10">      <cfset session.sessionuser=form.userid>  </cflock> 

  • Server scope

     <cflock scope="server" type="readonly" timeout="10">      <cfset variables.servername=server.servername>  </cflock>      <cflock scope="server" type="exclusive" timeout="10">  <cfset server.servername="CFMXXP">  </cflock>  

When to Lock

In short, always lock access to shared-scope variables. Too many developers have made the mistake of overlooking the necessity of locking access to these variables and have paid the price with unstable servers, crashing applications, and lost revenue. There is never an occasion when you should leave access to these variable scopes unlocked.

I know, maybe you're saying to yourself, "I only have three variables that I access in the entire application. How is this problem going to affect me? I don't have the traffic or user load required to bring down my server." Of course, all your buddies clap, "Good answer. Good answer." Well, that's your third strike and just like on Family Feud, you don't win the prize.

There also is no formula to when memory corruption occurs. I have seen applications that showed the first signs of instability with only one user traversing the application and others that seemed fine with more than one hundred users. However, when they crash, they all crash hard, regardless of load or how long it took to get them to the point that they crashed.

ColdFusion Lock Checking

In your ColdFusion Administrator, you have a section on locking. This section gives you the opportunity to change your lock settings for application, session, and server variable scopes. In your development environment, you should turn on the full lock checking option for each variable scope listed. This ensures that if you have not properly locked variables, an error is returned to your browser during testing.



Inside ColdFusion MX
Inside Coldfusion MX
ISBN: 0735713049
EAN: 2147483647
Year: 2005
Pages: 579

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net