CFTRANSACTION: Am I using it incorrectly?
Adobe Forums User May 24, 2014 1:52 AMJust so we don't get too far off track, keep in mind the code samples below aren't my true code. I'm stripping things down for illustration purposes only - I realize they're bad examples and lack CFQUERYPARAM.
So, to give a little background first... I started my ColdFusion programming career over a decade ago building fairly large e-commerce applications. Not Amazon scale, but not mom-and-pop shopping carts by any means.
In those days I often used CFTRANSACTION for situations where multiple INSERT or UPDATE queries relied on each other. For example, a form that inserts a new product into a database table, and inventory counts into a separate table.
For example:
<cftransaction>
<cfquery datasource="mydatasource" result="product_inserted">
INSERT INTO products (sku, price, title)
VALUES ('555-555', 2.50, 'Spider-Man T-Shirt')
</cfquery>
<cfquery datasource="mydatasource">
INSERT INTO inventory (product_id, inventory)
VALUES (#product_inserted.IDENTITYCOL#, 50)
</cfquery>
</cftransaction>
This insures that both tables are written to. If a query fails for some reason, the other won't be committed to the database.
Somewhere along the line however I started what I believe is a futile (and possibly bad) practice.
In some applications I have a ColdFusion template which (when passed an ID number via a URL variable) allows the user to edit a record via a form.
The first thing the page does is check for the required URL variable, and then pulls the records from the database. It then displays that record in a form for editing.
When the form is submitted, the page obviously checks for the URL variable again, the required form fields, and then queries to make sure the record exists (as you don't want to continue with the UPDATE if the URL variable isn't a valid record, right?
So, the processing page for the form update might have code like this:
<cftransaction>
<cfquery name="find_product" datasource="mydatasource">
SELECT *
FROM products
WHERE id = #url.sku#
</cfquery>
(some code here that checks the form data for proper type, etc.)
<cfquery datasource="mydatasource">
UPDATE products
SET myfield = #form.myfield#,
anotherfield = #form.anotherfield#
WHERE id = #find_product.sku#
</cfquery>
</cftransaction>
You see what I did there? Somewhere along the line in my programming history I just suddenly started putting CFTRANSACTION tags around blocks of code that used multiple queries, usually a SELECT statement and then an UPDATE statement that was then updating the record found via the SELECT statement. I started treating CFTRANSACTION as some sort of "lock", thinking that it was somehow ensuring that the SELECT and UPDATE statement were uninterrupted by another other user who may be invoking the same page, thus avoiding a race conflict for the record being edited. Please someone set my mind at ease and tell me this is actually not accomplishing that, and all I'm doing is slowing down my DB processes?
If my hunch is correct, and I've had a futile/bad habit for years, what would be the proper method for avoiding the above scenario?



