cftransaction запускает только первый cfquery, пропускает через секунду

Я пытаюсь записать в две разные таблицы, обе в одной базе данных. В одном CFTRANSACTION с двумя CFQUERY, первый CFQUERY будет вставлен правильно, а второй (также INSERT) просто пропущен. Не выдается никаких ошибок, я вижу данные в первой таблице, а комментирование первой INSERT позволит второй проходить по желанию.

Упрощенная версия моего кода:

<cffunction name="insertReport">
<cfset var strReturn="">
<cftransaction>
<cftry>
<cfquery name="updateTable1" datasource="DB1">
...
</cfquery>
<cfquery name="UpdateTable2" datasource="DB1">
...
</cfquery>

<cfcatch type="any">
<cfset errMsg = "#cfcatch.Message#">
</cfcatch>
</cftry>

<cfif trim(errMsg) eq ''>
<cftransaction action="commit">
<cfelse>
<cftransaction action="rollback">
<cfset strReturn = "Error: #errMsg#.">
</cfif>
</cftransaction>

<cfreturn strReturn>
</cffunction>

Это, наверное, что-то действительно простое, но я застрял. Любая помощь приветствуется.

2 ответа

Спасибо всем, кто помог. Оказывается, проблема заключалась в том, что мы используем CFQUERYPARAMs в CFQUERY вместо жесткого кодирования значений, и они генерировали исключения Null Pointer.

Похоже, что эти элементы CFQUERYPARAM правильно записали бы в базу данных, когда у нас был только один CFQUERY, но все равно выдало исключение Null Pointer, которое пропустило бы второй CFQUERY. Поскольку нулевой указатель выдавал только значение "#cfcatch.type#", а не "#cfcatch.Message#" или "#cfcatch.detail#", которое искала наша проверка ошибок, мы не отметили проблему.

Сейчас мы собираемся использовать jTDS, чтобы понять, решит ли это проблему.

Обновить

Я только что попробовал приведенный ниже код на CF11, и он работал нормально. Единственная ошибка, которую я получил, заключалась в том, что errMsg был неопределен, чего нет в вашем коде до <cfcatch> происходит. Я определил errMsg и перезапустил - все прошло успешно.

<cffunction name="insertReport">
    <cfset var strReturn="">
    <cfset errMsg = "">
    <cftransaction>

    <cftry>
        <cfquery name="updateTable1" datasource="DS1">
            INSERT INTO ...
        </cfquery>

        <cfquery name="UpdateTable2" datasource="DS1">
            INSERT INTO ...
        </cfquery>

    <cfcatch type="any">
        <cfset errMsg = "#cfcatch.Message#">
    </cfcatch>
    </cftry>

    <cfif trim(errMsg) eq ''>
        <cftransaction action="commit">
    <cfelse>
        <cftransaction action="rollback">
        <cfset strReturn = "Error: #errMsg#.">
    </cfif>

    </cftransaction>

    <cfreturn strReturn>
</cffunction>

<cfoutput>#insertReport()#</cfoutput>

Относительно нескольких источников данных

Согласно этому форуму Adobe и этому посту SO, вы должны зафиксировать изменения в каждом источнике данных, прежде чем переходить к следующему.

Согласно сообщению SO, это будет работать:

<cftransaction action="begin">

    <cfquery datasource="foo">
    select * from foo_test
    </cfquery>

<cftransaction action="commit"><!-- Commit before switching DSNs --->

   <cfquery datasource="bar">
    select * from bar_test
    </cfquery>

</cftransaction>

Обратите внимание, что если вы можете получить доступ к своим данным через один источник данных, используя три имени частей (например, fooDB.dbo.table), вы можете записывать в разные базы данных в одной <cftransaction>

Другие вопросы по тегам