I haven’t had much use for using locking in cfml. ...
# cfml-general
s
I haven’t had much use for using locking in cfml. But i would like to have a better understanding of when and why to use one. Could anyone give me some practical uses for cflock?
b
I tend to use it when dealing with initialization of data in a singleton
For example, the recent Oauth Exchange code I posted on the Lucee forum-- when the access token expires, I only want a single thread refreshing it.
So I use the traditional double-check lock pattern
Many of the times I've seen people use locks, it's unnecessarily (or incorrectly) but generally it will revolve around data created by the first thread who hits the logic but accessed by many threads and you only want that logic happening once
The other most common scenario would be to keep consistency across more than one variable whose state is available to more than one thread in the app. Such as
Copy code
function transferFunds( numeric amount ) {
  lock name="ledger" timeout=10 type="exclusive" {
    savings.debit( amount );
    <http://log.info|log.info>( 'Transferring funds...' )
    checking.deposit( amount );
  }
}
...
function getChecking() {
  lock name="ledger" timeout=10 type="readonly" {
    checking.getTotal();
  }
}

function getSavings() {
  lock name="ledger" timeout=10 type="readonly" {
    savings.getTotal();
  }
}
Imagine if one thread was in the middle of trasnferring $100 from savings to checking, while another thread called the getChecking() and getSavings() methods at the exact same time and the numbers didn't line up. So long as every access to the ledger used a readonly lock and all modifications used an exclusive lock, you could ensure consistency between the two values.
That second example rarely happens in your typical web app and it's only going to apply to consistency across multiple variables or data structures. There's never a need to lock a single variable (unless you're using
var++
or
var--
which isn't atomic/threadsafe, lol)
s
Interesting, thank you for the explanation, so when something encounters a lock does it error or doesn’t wait for the lock to finish?
I would assume the latter
b
It errors if it times out
Unless you disable
throwontimeout
in which case, it just moves on and it's up to your code to detect this if you care
But it will wait for the timeout
You have to be very careful with locking, especially with long time outs as heavy load can bring down a server fast due to code not releasing a lock!
a
This is probably inferentially covered by Brad's comment about the init code, but a race condition can be broader than that (so don't think "init code" necessarily). EG:
Copy code
doStuff() {
    someSharedScopeVar = somePointInTimeValue
    
    // calculation based on the value someSharedScopeVar was set to in this thread
    // more calcs
    // and more
    
    return someResultBasedOnThoseCalcs
}
If the bottom line is intrinsically connected to the starting value, then you probably won't want a second thread coming in whilst a first thread is in the middle of finalising its result; so one locks all that to make sure only only thread at a time will run that code. This might not be initialisation code, it might be fine for the code to run as often as needs-must, but it's important it only runs once at a time. One needs the code to be atomic. Of course there will also quite possibly be strategies to mitigate this... one should avoid having to write code like this if at all possible, but sometimes it's unavoidable / the right way to do things. Also note for this example I use
someSharedScopeVar
, but it could be any datum that is present in a way that multiple threads could access it whilst it's being worked on. It might be a row in a DB or a file or whatever. The point is if there are multi-statement operations that need to be atomic; they need to be locked. It's probably beneficial to think outside CFML specifically for this, and read up on synchronisation and race conditions in general. They're present anywhere there's code, so there will be more learned writing out there than you'll get from some CFML chat app 😉
👍 1