Well, at least if I could detect whether I am in a transaction I could write around this I think. But there is no way that I have found. No clear posting on how to do this.
First approach I used was to create a function that would open and close a transaction, then detect the error thrown. If the error was thrown I was assuming that we were in a transaction and thus could not open a new one, a fuction like this:
<CFSET var blnReturn = false>
<CFTRY>
<CFTRANSACTION>
<!--- emptry transaction tag --->
</CFTRANSACTION>
<CFCATCH type="Any">
<CFSET blnReturn=true>
</CFCATCH>
</CFTRY>
<CFRETURN blnReturn>
Unfortunatly, this does not work. When CF throws an error for nesting, even within the try/catch block for the purposfully nested transaction, the transaction wrapper is removed. Thus you are hosed if an error occurs later down the execution.
What to do then?
After much researching and failure, here is the approach I did find working. The trouble with this is, that there is no guarantee that it will work in future versions of CF, which I hope will introduce a simple function like InTransaction() . We are using the ColdFusion Java implementation of the Transaction Tag to find out whether we have a current transaction. This is the fully wrapped function.
<CFFUNCTION name="InTransaction" access="public" displayname="checks to see whether we are currently running a database transaction. returns true or false." output="No" RETURNTYPE="boolean">
<CFSET var objTrans ="">
<CFSET var blnActiveTransaction=false>
<CFSET var objCurrentTrans="">
<!--- Call to CF implementation of TransactionTag to expose Java functions --->
<cfobject type="Java" class="coldfusion.tagext.sql.TransactionTag" name="objTrans" action="create">
<!--- objCurrentTrans will become undefined if the Java function call getCurrent() returns Null,
otherwise this returns a pointer to current transaction instance --->
<cfset objCurrentTrans = objTrans.getCurrent()>
<cfif IsDefined("objCurrentTrans")>
<CFSET blnActiveTransaction=true>
</cfif>
<!--- return result --->
<CFRETURN blnActiveTransaction>
</CFFUNCTION>
This works in ColdFusion 8 and 7.
Cheers.
3 comments:
in railo you can do this as follows
getPageContxt().getDataSourceManager().isAutoCommit()
In CF9 you can use nested attribute in cftransaction tag.
Just a heads-up: I've simplified this and put it up on CFLIB: http://cflib.org/udf/isInTransaction. Am happy to change the attribution to your name if you can give me your details.
Thanks for blogging about this.
--
Adam
Post a Comment