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>