Locking session values

222 views
Skip to first unread message

Jonathan Brookins

unread,
Feb 23, 2015, 4:00:42 PM2/23/15
to lu...@googlegroups.com
When setting/getting session variables is it still necessary to cflock the process?

Alex Skinner

unread,
Feb 23, 2015, 4:18:44 PM2/23/15
to lu...@googlegroups.com

It's not necessary from a data corruption issue like it was in very old CF I forget the version number.  It may or may not be necessary from a race condition standpoint but that is based entirely on what you are using them for.

I'd lean towards no, but bear in mind that if you are using frames or multiple ajax calls with counters or otherwise you could come unstuck.

Alex

Sent from my phone

On 23 Feb 2015 21:00, "Jonathan Brookins" <jon.br...@gmail.com> wrote:
When setting/getting session variables is it still necessary to cflock the process?

--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lucee/ba1dd251-5e6c-46a0-98be-0e252306f273%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sean Corfield

unread,
Feb 23, 2015, 4:25:56 PM2/23/15
to lu...@googlegroups.com
On Feb 23, 2015, at 1:00 PM, Jonathan Brookins <jon.br...@gmail.com> wrote:
> When setting/getting session variables is it still necessary to cflock the process?

The simple answer is: probably not. You won’t get memory corruption due to not locking around session variable access (like you used to on ColdFusion back in CF5 and earlier). Since ColdFusion moved to Java — and in Railo and Lucee — that has never been a problem.

You can still get a race condition if you might have multiple requests (in the same session) running concurrently. A race condition means that multiple requests (threads) could access / update the data in such a way as to give you unpredictable results (not memory corruption).

Here’s an example:

var v = session.count++;

If you expect to get a continuous sequence of values, you might get a surprise if two requests from the same session hit this code at "the same time". The reason is that this is not an atomic operation so you might have:

* thread 1 reads session.count, gets 42
* thread 1 increments 42
* thread 1 stores session.count (43)
* thread 1 assigns 42 to v
* thread 2 reads session.count, gets 43
* thread 2 increments 43
* thread 2 stores session.count (44)
* thread 2 assigns 43 to v

But those could also be interleaved like this:

* thread 1 reads session.count, gets 42
* thread 2 reads session.count, gets 42
* thread 1 increments 42
* thread 1 stores session.count (43)
* thread 2 increments 42
* thread 1 assigns 42 to v
* thread 2 stores session.count (43)
* thread 2 assigns 42 to v

So it might matter, or it might not. Note that I’m assuming a local variable v in a function that is called on each request so the v for thread 1 and the v for thread 2 are separate variables. The point is just that you can "lose" increments.

If you don’t have ajax-based requests coming in, you’re much less likely to get multiple requests (but an impatient user pounding F5 could still cause them).

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)



Jesse Shaffer

unread,
Feb 23, 2015, 4:36:18 PM2/23/15
to lu...@googlegroups.com
As I understand, it is best practice, at least in ACF, to lock code that writes to any shared scope:

lock scope="session" type="readonly" timeout=30 { // BTW, you may know this already, but this timeout is not that the code should take 30 seconds to run,
                                                 
// it is, "wait 30 seconds trying to acquire the lock before throwing an exception."
   session
.key = "value";
}

lock scope="application" type="readonly" timeout=30 {
   application.key = "value";
}

I have spent a week or more debugging race conditions where the problem was back-to-back requests trying to modify/read the same session key at the same time, and the answer was a lock.  This was in ACF 9 btw.

Now, with Railo 4.1 and Lucee, all scopes are derived from an altered ConcurrentHashMap, which is supposed to eliminate those types of race conditions.  I have not thoroughly tested with our codebase so I still hold some reservation.  However, as we have to maintain cross-platform compatibility, we continue to use locks.  

TL;DR;
If you must support ACF or Railo 4.0 and below, yes it is necessary, otherwise no.

Sean Corfield

unread,
Feb 23, 2015, 4:50:07 PM2/23/15
to lu...@googlegroups.com
On Feb 23, 2015, at 1:36 PM, Jesse Shaffer <dajest...@gmail.com> wrote:
As I understand, it is best practice, at least in ACF, to lock code that writes to any shared scope:

Well, "best practice" is questionable since you can write to shared scopes perfectly safely if you can guarantee your actions are atomic and/or not subject to race conditions.

You would need type="exclusive" tho’ in order to protect a write, not type="readonly".

Jesse Shaffer

unread,
Feb 23, 2015, 5:14:45 PM2/23/15
to lu...@googlegroups.com
I stand corrected - I haven't had to write new code using locks in around 2 years, so I was going from memory, and for whatever reason readOnly came to mind first.  But yes, for writing to shared scopes it should be an exclusive lock.

Alex Skinner

unread,
Feb 23, 2015, 6:53:50 PM2/23/15
to lu...@googlegroups.com

You also might consider named locks as this allows more granular control again I think to say best practice is too broad.  Shared scope means defensive coding but how defensive depends on your usage.

A

Sent from my phone

--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.

Adam Cameron

unread,
Feb 23, 2015, 7:00:13 PM2/23/15
to lu...@googlegroups.com


On Tuesday, 24 February 2015 10:00:42 UTC+13, Jonathan Brookins wrote:
When setting/getting session variables is it still necessary to cflock the process?


Short answer (as others have alluded to): not intrinsically, no.

-- 
Adam 

Adam Cameron

unread,
Feb 23, 2015, 7:03:32 PM2/23/15
to lu...@googlegroups.com


On Tuesday, 24 February 2015 10:25:56 UTC+13, Sean Corfield wrote:
On Feb 23, 2015, at 1:00 PM, Jonathan Brookins <jon.br...@gmail.com> wrote:
> When setting/getting session variables is it still necessary to cflock the process?

The simple answer is: probably not. You won’t get memory corruption due to not locking around session variable access (like you used to on ColdFusion back in CF5 and earlier). Since ColdFusion moved to Java — and in Railo and Lucee — that has never been a problem.

You can still get a race condition if you might have multiple requests (in the same session) running concurrently. A race condition means that multiple requests (threads) could access / update the data in such a way as to give you unpredictable results (not memory corruption).

Here’s an example:

        var v = session.count++;



Michael Offner

unread,
Feb 24, 2015, 2:09:28 AM2/24/15
to lu...@googlegroups.com
From a technical standpoint, Lucee is using concurrenthashmap (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html) for all scopes and structs.
In fact a adaptation of the implementation pointed out above that is improved for the Lucee runtime.

So there is no need to lock any access to scopes, this is simply a waste of time.

Cflock should only be used to lock a process happening in your application, like for example this
Session.whatever=1;
Sleep(1000);
Session.whatever=2;
Sleep(1000);
Dump(session.whatever);

This process is not atomar, so the dump output could be 1 or 2 when you have multiple requests.
To make sure you get 2 in this example wrap the code with cflock. 

In short therms, setting or getting data from any scope is atomar, but your code maybe is not...

Micha
--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.

Jonathan Brookins

unread,
Feb 24, 2015, 7:57:15 PM2/24/15
to lu...@googlegroups.com
Thanks for the discussion, everyone.  Very instructive.
Reply all
Reply to author
Forward
0 new messages