cftransaction 101: Docs say this: ```If you do not...
# cfml-general
d
cftransaction 101: Docs say this:
Copy code
If you do not specify a value for the action attribute, automatic transaction processing proceeds as follows:

If the cfquery operations within the transaction block complete without an error, the transaction is committed.
If a cfquery tag generates an error within a cftransaction block, all cfquery operations in the transaction roll back.
If there's a try/catch, does that affect automatic transaction processing?
r
I do not believe so, but that has been my experience
I generally wrap my queries in a try/catch and if one of the queries fail I rollback the transaction in the
catch
block
a
Are you altering db schema at all? As that causes the translation to commit as well on some DB engines (found out the hard way!)
w
personally i wouldn't consider using a cftransaction without providing all the sensible attributes for it (as opposed to just an unadorned cftransaction block). and i would always have it in a try catch that explicitly BEGINs and COMMITs and ROLLBACKs. since it's really exerting more control over that block of queries, i say control it, including specifying the isolation type etc
👍 1
d
Thinking about it, I'm with you folks on being explicit about it. In general I like less code, because it's clearer, that I don't think that's the case here, more the opposite. (No schema changes, just updating records in several tables, as an atomic thing.)
👍 1
t
I found a usecase for being not explicit, just to throw it out there...
if you have nested transactions, being explicit can bite you. I have some code that I've wrapped in a transaction to be atomic. But then i have my tests wrapped in a transaction so they can roll back all their database changes at the end of the test. So when my tests called this code, it ended up in a nested transaction situation.
When my code called commit to commit the inner transaction, it also commited the outer transaction.
And as far as I could tell, there was not a way to name the transactions to allow it to tell which one to do. If I don't explicitly call commit, and just let it do it's auto thing, it deals with it correctly, only committing the inner transaction, and rolling back the outer one.
👀 1
d
Interesting. Yuck.
💯 1
r
I have tried to avoid nested transactions... Now I see why 😛
t
yeah. It's semi-documented (and the fact that is references CF9 is kind of a red flag...):
• You can now nest cftransaction tags. Typically, ColdFusion 9 does not support nested transactions, but you can embed one cftransaction tag inside another. If you nest these tags, only the outermost cftransaction tag takes effect.
• This feature lets you write functions that must run in a transaction without considering whether the function is called by code that is inside a cftransaction tag. Use a cftransaction tag in the function. If the calling code is in a transaction, the tag has no effect. If the calling code is not in a transaction, the tag starts the transaction.
When it says "If the calling code is in a transaction, the tag has no effect." what it means is "if you try and start a transaction within another one, it will have no effect...." If you commit or rollback the transaction that didn't get started, it's not ignoring that one....
😂 1
d
I remember writing some wrappers long ago to keep track of whether it was already in a transaction, not start another one if so, and commit or roll back when the last layer popped off the stack. No plans to resurrect that stuff 🙂