CFTRY/CFCATCH and CFTRANSACTION
CF Version: 2016,0,03,300466 (Standard)
DB Driver: com.microsoft.sqlserver.jdbc.SQLServerDriver
I don't know if this is a bug or a feature, but when a query fails within a cftry/cfcatch block that is surrounded by a cftransaction tag, and that query is executed again in the cfcatch block (i.e. for timeout or deadlock purposes), all queries that ran before the cftry/cfcatch block are rolled back. For instance:
<cftransaction>
<cfquery name="query_1" datasource="#my_ds#">
INSERT INTO Table1(Field1, Field2)
VALUES(
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#val1#"/>,
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#val2#"/>
)
</cfquery>
<cfquery name="query_2" datasource="#my_ds#">
UPDATE Table2
SET Field1 = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#val3#"/>,
WHERE id = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#id#"/>
</cfquery>
<cftry>
<cfquery name="query_3" datasource="#my_ds#">
INSERT INTO Table3(Field1, Field2)
VALUES(
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#val4#"/>,
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#val5#"/>
)
</cfquery>
<cfcatch>
<cfquery name="query_3" datasource="#my_ds#">
INSERT INTO Table3(Field1, Field2)
VALUES(
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#val4#"/>,
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#val5#"/>
)
</cfquery>
</cfcatch>
</cftry>
<cfquery name="query_4" datasource="#my_ds#">
INSERT INTO Table4(Field1, Field2)
VALUES(
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#val6#"/>,
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#val7#"/>
)
</cfquery>
</cftransaction>
If query_3 fails for any reason, the query is executed again in the cfcatch and processing continues. However, query_1 and query_2 are rolled back. Separately, query_4, which occurs after the cftry/cfcatch block is not rolled back.
Granted, this is a simple example and in the real world you would add conditional processing and other logic to the cfcatch to rethrow the error if that query failed. I wanted to make it as simple as possible, though, to illustrate the point.
The implication here is that you could be defeating the purpose of cftransaction and end up with orphaned records that may have been inserted after the cftry/cfcatch. Moreover, if this condition occurred towards the end of the request and you redirected the user to a "thank you" page or something similar after the DB operations, the user would be blind to the fact that there were any issues with the request.
???
-Eric
