ColdFusion MX Session Variables and Locking
I have recently been encountering many ColdFusion MX developers who are afraid of using session variables. They probably have good reason to fear, for years lore of scrambled session variables has permiated many developer's dreams of well running applications. From a security standpoint things couldn't be worse. There exists the possiblity of mixing up two concurrent visitors' data. In a shopping cart for example, it would be possible for one visitor to purchase the items in another's cart if the server is under sufficient load.
Understanding those fears, I have yet to encounter serious session variable issues since I came across Macromedia's documentation on this item before I started using them heavily. I still won't keep sensitive user data such as passwords or usernames in a session variable, instead carrying a state of logged in through the application with a UUID for that session. The way to handle session variables is detailed here:
But for a more clear explanation, let me cut to the chase. You *must* use cflock for setting variables, and you should use it for reading variables with the readonly attribute set. Let me start with the detractors to using cflock and you can decide if you really want to use session variables, or if another method will suffice, such as using the database, cookies, or a combination of the two.
The issue with ColdFusion actually occurs because it is a modern application server that threads instead of instantiating, see my earlier blog PHP vs. Coldfusion. The crux of the situation is that when ColdFusion is under load it will spin off threads with their own memory for each request. If there are too many requests the ColdFusion server can return out-of-date data, such as returning the wrong cart ID, if it has been recycled, etc… This can cause problems in a heavily used site, or it can even cause crashes if an object is being updated while another is trying to read it, but more than likely it will just return stale data. These issues only occur when using variables that use shared states such as session, application, and server.
To avoid this, you can force ColdFusion to instantiate instead of thred by using cflock. If you wrap a tag with an exclusive cflock, while that tag is being updated, the application server will create a new instance of that variable for the requester, this will prevent any possible confusion of who that variable belongs to. The downside to this is that it forces the ColdFusion server to use new memory to store that object instead of using its normal threading system. If your CF server is adequately stocked with memory however, this should not be an issue.
Here is a code example:
That was an example of code that could have an issue, if you are updating this variable, and the shopper is requesting that same variable it is possible that the update could be held in que and the shopper could get the old version of SESSION.myVar. Here is an example of this same scenario with thread-safe locking.
Hopefully you will experience no issues with mixed up session variables if you use this method, however there is still the possiblity that you may. I would use client variables and cookies wherever practical to carry session variables and avoid session variables, however one place where I have found it to be impossible to avoid session variables is when using structures for a visitor. Unfortunately client and cookie scoped variables can not use structs.