A reader just added a comment to a blog entry I had completely forgotten about I had written: Ask a Jedi: CFLOCK in CFSCRIPT. The blog entry details two UDFs I wrote so I could both read and write in a locked fashion via cfscript. I thought I'd quickly show an example of how you can lock now in ColdFusion 9. I had to do this for the first time in Picard a few days ago.
I have a service CFC which wraps a save operation for Foo entities. I have two columns, aaa and bbb (sorry for the dumb names, but under heavy NDA here) that must be unique across the database. I wanted my logic then to simply say: Get a Foo with the same AAA, and if it isn't the same object, it's an error. Ditto for BBB. For this to work though it has to be single threaded. Here is the code I came up with, and notice how the lock wraps it:
public function saveFoo(foo) {
//Ensure we lock so we can check for dupes
lock name=variables.lockname type="exclusive" timeout="30" {
//Alrighty, first check for a dupe AAA
var dupe = entityLoad("foo", {aaa=foo.getAAA()}, true);
if(!isnull(dupe) && dupe.getId() != arguments.foo.getId()) throw "A foo with this AAA already exists.";
//Check for a dupe BBB
var dupe = entityLoad("foo", {bbb=foo.getBBB()}, true);
if(!isnull(dupe) && dupe.getId() != arguments.foo.getId()) throw "A foo with this BBB already exists.";
//Ok save this puppy
entitySave(foo);
return foo;
}
}
I'm not a big fan of the syntax (and the CFML Advisory committee has agreed on a nicer syntax), but it's good enough for now. FYI, variables.lockname
is global to my CFC and used across the component.
Archived Comments
might want to add this to the cookbook? :)
_Maybe_. I'm not so sure though as it is rather simple.
Just out of curiosity - has the new syntax benefited you in any way? I know that you've been working with it quite a bit lately so I'm just curious as to whether or not you'll dive into it. This works pretty good for my money...
<cflock
timeout = "time-out in seconds"
name = "lock name"
scope = "Application|Server|Session|Request"
throwOnTimeout = "yes|no"
type = "readOnly|exclusive">
<!--- CFML to be synchronized. --->
</cflock>
Benefited? Hell yes. This is purely a personal thing, but I much prefer writing my CFCs in script. It feels much more natural to me. So being happier while coding to me in a massive #win.
I am with Ray - On top of the tons of typing it saves me it just is more enjoyable to code in and a happy developer is a productive developer!
Thanks for the cfscript cflock code sample, as always.
To everyone: remember that a named lock (or scope-lock for that matter) obviously cannot handle locking across multiple CF instances (such as in a cluster), so a cflock may not always be appropriate if you are in a multi-server environment.
For Ray's sample, since it involves database, cftransaction would probably be more appropriate since it would handle database concurrency even in a multi-server CF infrastructure.
Good point there. I almost always tend to work on a single instance, so it's not something I need to be concerned with.
As a eager-to-learn CFC in CFSCRIPT noob - any articles you fine gentlemen might suggest?
The docs. :) There is a section on CFML and CFSCRIPT. It was updated for CF9 to cover new stuff, like abort, writeDump, lock, etc. Ben Nadel has an article or two on using Query in cfscript. And - well, Google is always your friend. :)
Thanks Ray - Will do.
As a "Jedi Apprentice" I want to see if I can mimic the master whenever possible. :)
This is new to me as well. I'm certainly not yet a Master!
Hey Raymond - looks like there is a formatting error in the code example here.
A lot of my old posts have this issue. :) I'll fix it up sometime soonish. :)
No worries, just wanted to make sure you were aware.
Fixed.