Securing CFC Variables Under Load
I've been using CFC's for processing for a little while now and haven't come across this issue before as most of our applications run internally and don't get much load. I have an application running now that processes payments online for renters and since they are all due on the first of each month, there's a ton of activity for 1-2 days and then it dies off again. I noticed the last time this was heavily used (March 1) that when then 2 or more people are paying online in very close time proximity to each other, the data I'm capturing to record the payments is missed up, and often related to the payment information directly before or after the incorrect one. It's like when someone else enters the CFC, it's over-writing some of the variables within the CFC.
Here's some of the code (simplified):
1. I'm setting the CFC's and some other variables into the application scope in Application.cfm on start of the application:
<cfif IsObject(application.commonCFC) EQ false OR URL.init NEQ "">
<cflock type="exclusive" timeout="30">
<cfset application.commonCFC = createObject("component","assets/cfc/common")>
</cflock>
</cfif>
2. A user fills out a form on a page and submits the payment data back to the same page.
3. I'm setting the payment amount and formatting it:
<cfset pmtTotal = NumberFormat(form.pmtAmt, "99.99")>
4. I post it to the CFC:
<cfset postPayment = application.commonCFC.postCCPayment('#session.accountNum#','#form.ccNum#','#pmtTotal#')>
5. In the CFC, I've wrapped the body of it in a cftransaction block to try to prevent multiple executions at the same time.
6. After that, I'm setting some variables in the CFC:
<cfset pmtAmt = arguments.pmtAmt>
<cfset feesAmt = 0>
<cfset totalAmt = NumberFormat((pmtAmt + feesAmt), "99.99")>
7. Then submit it to the payment gateway.
8. Then capture the results in a database table, including the pmtAmt, feesAmt, and totalAmt.
What I notice is that in the database capture (the last thing to execute), the feesAmt and totalAmt are not correct once in a while (usually when 2 transactions are very close together). I'm assuming the pmtAmt IS correct becuase it matches what was captured by the processor and matches the amount due for the tenant. I notice this by running a quick query that pulls records if the pmtAmt + feesAmt <> totalAmt. I did have the variables in the cfc set to <cfset var xxxx.../> previously, but had to take this out when I added the cftransaction tag as they weren't immediately following the cfarguments then (I'm on CF8).
Why would the other variables be changing mid-stream? How can I prevent this? I need essentialy single-user access to this process until the function is done. I've thought about cflock, but have had trouble with that in the past with people getting locked out and not being able to obtain the lock. There has to be a simpler way.
Thanks for any help!
