ошибка превышения тайм-аута cfhttp

Пожалуйста, рассмотрите следующий код:

Я отправляю запрос SOAP, передаю число и возвращаю 7-8 полей информации. Число, которое я передаю в своем мыльном конверте, извлекается из файла CSV из 170 000 записей. Вот фрагмент кода того, что я делаю:

<cffile action="READ" file="http://filepath/Myfile.csv" variable="FileContent">
<cfset CSVArray = CSVtoArray(FileContent)>

<cfset CSVArrayLength = ArrayLen(CSVarray)>

Total Records:<cfdump var="#CSVArrayLength#" >

<cfloop index="LoopCount" from = "2" to = "#CSVArrayLength#">

<cfsavecontent variable="soap"><?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:vtsInfoLookup" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:vtsInfoLookup">
    <SOAP-ENV:Header>
        <userName>xyz</userName>
        <password>JiunskeT1</password>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
           <infoLookup SOAP-ENV:EncodingStyle="http://schemas.xmlsoap.org/soap/encoding/" >

                  <Number><cfoutput>#CSVArray[LoopCount][2]#</cfoutput></Number> 
               <userName>xyz</userName>
               <password>passwd</password> 
           </infoLookup>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

</cfsavecontent>

<cfhttp url ="https://myurl/abc.php?wsdl"  method = "post"  result =   "httpResponse" throwonerror=   "Yes">
    <cfhttpparam type="header" name="accept-encoding" value="no-compression" />
            <cfhttpparam type="header" name="content-type" value="application/soap+xml">

            <cfhttpparam type="header" name="content-length" value="#len(soap)#">
            <cfhttpparam type="xml" value="#trim(soap)#">

</cfhttp>

<cfset XMLResponse = XmlParse(httpResponse.fileContent.Trim()) />
    <cfset arrNumber = XmlSearch(XMLResponse,"//*[name()='Number']") />
    <cfset Number = trim(arrNumber[1].xmlText)>


    // Similarly parsing for other 7-8 fields


     <cfquery name="vQuery" datasource="XX.XX.X.XXX">

    INSERT INTO 



          VALUES (<cfqueryparam cfsqltype = "cf_sql_varchar" value = "#trim(Number)#" null = "#NOT len(trim(Number))#"/>,

                     // 7 - 8 fields more here
                   )



    </cfquery>   


</cfloop>

Причина, по которой я начинаю с 2, заключается в том, что в моем CSV-файле имя столбца находится в первой строке. Номер начинается со второй строки в CSV. Вот почему я упомянул #CSVArray[LoopCount][2]# выше

Я использовал функцию CSVToarray, как упоминалось выше здесь

Поскольку в моем Сервере-->Настройки значение для запросов времени ожидания после ( секунд) установлено на 7200 секунд, время ожидания моего запроса истекло через 2 часа с сообщением об ошибке:

Запрос превысил допустимый срок Тег: cfhttp

Итак, из 170 000 записей в CSV он остановился после вставки 19 000 записей в SQL Server 2008 в результате тайм-аута запроса.

Есть ли способ сделать мой код эффективным? Прочитайте где-нибудь людей, предлагающих использовать <cfthread> ?


person John    schedule 04.09.2014    source источник
comment
вы всегда можете увеличить время ожидания только для этой страницы. Или вы можете использовать этот csv для создания файла .sql, который затем можно выполнить непосредственно с сервером sql, а не передавать 170 тыс. различных запросов в sql. Или разбейте вставки на куски, скажем, по 1000 вставок на кусок.   -  person Kevin B    schedule 04.09.2014


Ответы (1)


Увеличьте время ожидания http + время ожидания страницы. Если вы работаете с таким большим количеством записей, всегда старайтесь делить записи на небольшие куски.

Вставка 17k записей и вызов запроса на вставку в цикле невозможны.

Вы можете просто увеличить производительность, разделив (пример: 17000/2000 = 9 текстовых/SQL файлов) и использовать функцию SQL для импорта данных в БД из SQL или текстового файла.

queryObj = new query();
queryObj.setDatasource(session.datasource);
result = queryObj.execute(sql="LOAD DATA INFILE '#VARIABLES.textPath#' INTO TABLE tblEmployee FIELDS TERMINATED BY ':,:' LINES TERMINATED BY '\r\n'  (emp_Name,emp_City)");

В текстовом файле: новые строки добавляются в новую строку '\r\n', а поля разделяются символами ':,:'

person Sks    schedule 05.09.2014
comment
это был бы хороший способ передать тяжелую обработку в БД. Но я считаю, что вам не нужно конвертировать в несколько файлов, если вы отправляете их в БД. Чтобы быть в безопасности, просто запустите процесс в отдельном потоке. - person CFML_Developer; 05.09.2014