I receive several questions a week about locking, and the need for in ColdFusion MX, and so I thought it worthwhile to post a reply that I just sent to a user …
Locking in ColdFusion, and the tag specifically, has two primary uses, and these must be distinguished. The first use of has nothing to do with variables or shared memory, and everything to do with single-threading events. For example, if you had code that wrote to a specific file using , you’d never want two requests to write at the same time (or you’d risk trashing the file). You’d use a named lock to ensure that only one write happened at a time. is used to protect any code or operation that is not multi-thread safe. (This also applies to many CFX tags, COM objects, and more). Obviously, this locking need is every bit as relevant in CFMX as it was previously.
The more common use of locking is to protect shared memory from corruption. Let me explain. There are three scopes in ColdFusion that may be accessed by more than one request at any given time, these are SERVER, APPLICATION, and SESSION. Prior to ColdFusion MX, ColdFusion had a serious limitation in that if one request attempted to read or write shared memory while another request was in the middle of a write, then memory corruption could occur. This was never an issue with concurrent reads, but any activity concurrent to a write could cause problems. And these problems were tough to diagnose, the results of memory corruption can be erratic, delayed, and very inconsistent. And so we all got used to locking shared memory access, using LOCK=”exclusive” for writes and LOCK=”readonly” for reads.
But preventing memory corruption is not the only reason to lock shared memory. There is actually another reason, one that has nothing to do with a ColdFusion limitation, and everything to do with multi-threaded applications in general. Consider the following scenario; you have ten variables in APPLICATION that your code is updating, and mid-update another request reads those variables so that it has five old values and five new values. Is that a problem? Maybe, and maybe not, it depends on your code and application needs. This is what is known as a “race condition”, a situation where unpredictable behavior could result from the execution of code by two or more requests without proper sequencing. Race conditions are neither inherently bad nor good, but their results may cause problems for you depending on what your application is doing. If this type of condition is an issue for you, then you need to control execution sequence, and in ColdFusion this is achieved by using tags.
So, is the locking of shared memory still needed in ColdFusion MX? The answer is that it depends on why you are locking. ColdFusion MX does not suffer from the memory corruption that plagued prior versions, and so not locking will not harm ColdFusion at all. If the only reason that you ever locked shared memory was to prevent memory corruption, then no, there is no need to lock. But race conditions are still an issue, and if you are concerned about them then you still need to lock access to shared memory. Of course, race conditions may in fact be an issue that you never paid attention to because you were locking anyway (to prevent corruption).
The bottom line, locking is still needed for any code that is not multi-thread safe. And locking shared memory access is needed in order to prevent race conditions, if those are an issue. But locking merely to prevent memory corruption is, thankfully, a thing of the past.

4 thoughts

  1. Just for clarity’s sake, where does CF handle the management of complex variables? Does it handle it at the lowest (simple value) point in the data object, or at the highest level (structure, query, array, etc) of the data object?
    For example, if you have a variable, called "settings", in the Application scope that is a structure with 10 keys, does CF manage the read/writes at the "settings" structure level, or at the "settings" key level (i.e. does management occur at the highest level, or the simplest level value–which would be a "simple" value?)
    It’s important to know whether race conditions can occur further down in the hierarchical tree.

  2. I understand race conditions for server and application scope. The best practices uses the session scope in its example for a race condition. How is this possible? I thought session scope was unique to the user so should have no problem. In theory you could have one user session issuing multiple calls to the server (separate frames executing simultaneously comes to mind) so is this the only time you would worry about it?

Leave a Reply