Locking In CFML

viraginitysplashInternet and Web Development

Nov 10, 2013 (3 years and 11 months ago)

105 views

Locking

In CFML

Locking in CFML

-

Why

-

How

-

What

-

When

to lock?

Understand Locking

Locking in CFML

Agenda




The problem



Critical ressources



Shared Scope Variables



<CFLOCK>



Nested locks



Locks and pointers



Name Locks



Lock Administration



Client Variables *



Restrict number of


simultaneous requests *

* page not in CF
-
Europe presentation



Q & A *



Links *

Locking in CFML

Symptoms of a locking problem

-

unexplained “losses” of session


or application variables

-

server crashes

-

CF
-
Server consuming more


and more RAM

-

slow applications

Allthough these symptoms do not
indicate that there MUST be locking
issues, wrong locking (or no locking at
all) is one of the most likely causes for
the mentioned problems.

Locking in CFML

Multithreading

The ability of a program to perform multiple
tasks at the same time.

Exanple: eMail client

Read messages and
download new messages
from the server at the
same time

Locking in CFML

Multithreading

Advantages

-

performance / saves time

-

(system
-
) security

Drawbacks

-

programs are more


complicated to write

-

not easy to implement

Locking in CFML

Multithreading in ColdFusion

ColdFusion can handle multiple requests at the
same time

Every request is assigned to a thread

Additional requests will be queued

Within a thread the request is serialized

Number of Worker Threads can be set in CF
-
Administrator

Locking in CFML

Critical Ressources



Shared Scope Variables



Files



Component objects (COM, CORBA, Java)



All ressources that could cause problems



or loose performance if they are used by



more than one client at the same time

Locking in CFML

Shared Scope Variables



Server
-
Scope



Application
-
Scope



Session
-
Scope

Available for EVERY client of EVERY
application on that server

Available for EVERY client of ONE
SINGLE application

Available for ONE SINGLE client of
ONE SINGLE application

Frames, multiple submits, reload/redirection, etc. can
cause concurrent access with session variables!

Locking in CFML

<CFLOCK>

Identification

Type

Error Handling

NAME
or

SCOPE

TYPE=“Exclusive”


vs.

TYPE=“ReadOnly”

TIMEOUT and
THROWONTIMEOUT

Category

Attributes

Locking in CFML

<CFLOCK> and Shared Scope Variables



Lock

EVERY SINGLE

access



Lock the entire scope



use the correct locking type



lock only what needs to be locked

Explained on
pages “pointers
and structures”
and Q&A!

Locking in CFML

Example: store query recordset in application





variable

Wrong:

<CFLOCK scope=
"Application"

Timeout=
"10"
type=
"Exclusive"
>


<CFQUERY datasource=
"#DSN#"

name=
"application.customers"
>


SELECT * FROM tblCustomers



</CFQUERY>

</CFLOCK>

Better:

<CFQUERY datasource=
"#DSN#"

name=
“customers"
>


SELECT * FROM tblCustomers

</CFQUERY>

<CFLOCK scope=
"Application"

Timeout=
"10"
type=
"Exclusive"
>


<CFSET application.customers = customers>

</CFLOCK>

Locking in CFML

Client Variables and Locking

client variables are NOT stored in server RAM, but

in DB, Registry oder Cookies



operating system or DB engine will take care of


concurrent access



we do not need to lock client variables with


ColdFusion

Locking in CFML

Nested Locks



Deadlocks possible

<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"ReadOnly"
>


<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>


Code...


</CFLOCK>

</CFLOCK>


Template 1:

<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>


<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"Exclusive"
>



Code...


</CFLOCK>

</CFLOCK>


Template 2:

<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"Exclusive"
>


<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>


Code...


</CFLOCK>

</CFLOCK>


Only nested locks
make deadlocks
possible!

Consider what might happen if
those templates are executed
at the same instant!

Locking in CFML

Avoiding Nested Locks

<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>


<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"Exclusive"
>


<CFSET session.DSN = application.DSN>


<CFSET application.bgcolor = session.bgcolor>


</CFLOCK>

</CFLOCK>


<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"ReadOnly"
>



<CFSET dsn = application.DSN>

</CFLOCK>


<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"ReadOnly"
>



<CFSET bgcolor = session.bgcolor>

</CFLOCK>


<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>






<CFSET application.bgcolor = bgcolor>

</CFLOCK>


<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"Exclusive"
>


<CFSET session.DSN = DSN>

</CFLOCK>


Same result without nested locks:

Locking in CFML

Nested Locks


Avoid nested locks if at all possible

(performance issues, danger of deadlocks)

1. session scope


If you can’t avoid nesting, always lock in the
following order:

2. application scope

3. server scope



“Local out” approach

Locking in CFML

Locking of Pointers

Pointer: points to a structure (is NOT a real copy!)




<CFSET application.userData = session>

Changing the pointer also changes initial structure.

<CFSET myPointer = myStruct>

Shared scope variables are structures!



<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>



<CFSET application.userData = session>


</CFLOCK>



<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"ReadOnly"
>



<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>



<CFSET application.userData = session>


</CFLOCK>


</CFLOCK>




<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"ReadOnly"
>



<CFSET temp = application.userData.bgcolor>


</CFLOCK>







<CFSET temp = application.userData.bgcolor>



<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"ReadOnly"
>



<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"ReadOnly"
>



<CFSET temp = application.userData.bgcolor>


</CFLOCK>


</CFLOCK>





<CFSET application.userData.bgcolor =
"##EEEEEE"
>





<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>



<CFSET application.userData.bgcolor =
"##EEEEEE"
>


</CFLOCK>




<CFLOCK scope=
"Session"

Timeout=
"10"

type=
"Exclusive"
>


<CFLOCK scope=
"Application"

Timeout=
"10"

type=
"Exclusive"
>



<CFSET application.userData.bgcolor =
"##EEEEEE"
>


</CFLOCK>


</CFLOCK>


<CFSET application.myVar =

123

>

does not only access the key “myVar”, but
accesses the structure “applciation”. So lock the entire scope! Always!!

Locking in CFML

Name Locks

Name idetifies the lock and denies access to

protected ressource for all locks
with the same

name

Use it for all critical ressources except shared

scope variables, e.g.



Verity



<CFFILE>



COM
-
Objects

Recommended: use a naming convention!

Locking in CFML

Limit the number of simultaneous requests

Some ressources will dramatically loose performance if they receive too

many simultaneous requests. Some others (e.g. some FTP servers) will only

accept a certain number of simultaneous requests from the same client.

Name locks can be used to limit the number of simulatneous requests to

a certain ressource, even if concurrent access is not a problem.

<CFSET myLockName =
"Lock_FTP_MyServer_"

& RandRange(1,3)>

<CFLOCK name=
“#myLockName#"

t
imeout=
"10"

type=
“Exclusive"
>



<CFFTP . . .>

</CFLOCK>


You need to create a certain number of possible lock names, for example

using the functions for random numbers:

Because only three different lock names are possible, there will never be

more than three simultaneous requests from CF to FTP server.

Locking in CFML

Lock
-
Administration

Single Threaded Sessions

All thread with the same sessionID are serialized



concurrent access with session variables impossible



performance drawbacks (e.g. with frames)



template timeouts more likely to occur

Locking in CFML

Lock
-
Administration

Variable Scope Lock Settings


No automatic checking or locking


Full checking


Automatic read locking

Locking in CFML

Lock
-
Administration

Variable Scope Lock Settings


No automatic checking or locking



developer is responsible for proper locking



good performance but dangerous


Use this setting for production servers


with
TESTED

applications

Locking in CFML

Lock
-
Administration

Variable Scope Lock Settings


Full checking



every unlocked access throws an exception



secure, but small performance drawbacks



use it for development servers



for shared Servern



Name Locks also throw exceptions

Bug warning!

Not locking
IsDefined()

when
using shared scope variables
will NOT cause an exception!
But,
IsDefined(“shared_scope_var”)
MUST be locked, too!!

Locking in CFML

Lock
-
Administration

Variable Scope Lock Settings


Automatic read locking



every read access is automatically locked



quite secure, but has serious performance drawbacks



useful if you need to add locks to an older


application



write acesses must be locked manually

Locking in CFML

Summary

1. Lock EVERY access

2. If possible sum up accesses in a single lock, but,

3. Lock only what needs to be locked

4. For Shared Scope Variables always use the SCOPE
attribute

5. Use the correct locking type

6. Avoid server scope on shared servers

Locking in CFML

Summary (continued)

8. THROWONERROR=“Yes” ist useful, but, you need
to catch exceptions with CFTRY/CFCATCH

9. Avoid pointers between different scopes vermeiden.
Better use StructCopy() oder Duplicate().

10. If pointer can not be avoided: lock both scopes.

11. For production servers use “No automatic checking or


locking” setting (with TESTED applications only!)

12. For development server use “Full checking” setting

7. Avoid nested locks; if you need to nest locks, use l
ocal
out approach


Locking in CFML

Q & A

<CFLOCATION URL=

page.cfm


ADDTOKEN=

Yes

>

appends session.URLToken to the
URL. Don‘t I have to lock that kind of access to shared scope variables, too?

ADDTOKEN=“YES” does append CLIENT.URLToken instead of SESSION.URLToken. In
the documentation of CFLOCATION only one small remark reveals the difference:

clientManagement

must be enabled”. So it is a client variable and we don’t have to lock
those.

Why do I have to lock the entire scope when using shared scope variables? Shouldn‘t it be
sufficient to lock the single variable I try to access?

When accessing a shared scope variable, we always access the structure as a whole.
There‘s no use in locking a single element, if the bigger context can still be compromised.
You should ALWAYS lock the entire scope.

Due to security restrictions you can not use structure functions with the server scope.
(
<CFLOOP collection=

#server#


item=

key

>

will not work either). But still it is a
structure and must be locked entirely when using a server variable.

Locking in CFML

Q & A

Why do I have to lock EVERY single access to shared scope variables? One single unlocked

access surely will not harm the locked variables...

WRONG!

It is very important to understand how locks work. A lock only prevents
simulatneous accesses from within other locks with the same NAME or SCOPE attribute. If
you lock the application scope, it is not protected against unlocked access, but only against
access from within other locks with SCOPE=“application”.

That’s why name locks are a bit difficult to use. If two locks have different names, they still
can access the same ressource simultaneously and they can still cause concurrent access
problems. Using a naming convention for locks can help you to manage lock names more
easily.

What kind of naming convention should I use for name locks?

Actually that doesn‘t matter at all, as long as you follow your convention strictly. For
example a lock name could be “Lock” + protected ressource, e.g.

“Lock_files” or “Lock_ftp”.

Locking in CFML

Links

Best practices:

http://www.macromedia.com/v1/Handlers/index.cfm?ID=20370&Method=Full


A comprehensive guide:

http://www.depressedpress.com/DepressedPress/Content/ColdFusion/Guides



/Locking/Index.cfm


BF on CF: Lock it or loose it!

http://www.sys
-
con.com/coldfusion/article.cfm?id=135

Locking in CFML

Still got questions?

Christoph Schmitz

eMail: info@procept.net



Latest version of this presentation

is available for download at

http://www.procept.net