SSRS ReportExecutionServce.LoadReport застревает

#c# #reporting-services #ssrs-2016 #ssrs-2014

#c# #службы отчетов #ssrs-2016 #ssrs-2014

Вопрос:

Рассмотрим следующий пример кода:

 using System.Data.SqlClient;

namespace ReportLoadTest
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var con = new SqlConnection("...your connection string here..."))
      {
        con.Open();
        var trans = con.BeginTransaction();
        var cmd = con.CreateCommand();
        cmd.Transaction = trans;
        cmd.CommandText = @"insert SomeTable(...columns...) values (...); select scope_identity()";
        var rows = cmd.ExecuteScalar();

        var rs = new SSRS.ReportExecutionService();
        rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
        rs.Url = "http://localhost/ReportServer/ReportExecution2005.asmx";

        var ei = rs.LoadReport("/Folder/Folder/Some report", null);
      }
    }
  }
}
  

При каких условиях эта программа «застряла» бы при вызове ReportExecutionService.LoadReport ?

Под зависанием я подразумеваю 0 CPU, 0 I / O — вызывающая программа, службы отчетов или SQL Server вообще не добиваются прогресса.

Ответ №1:

Эта программа застрянет, если загружаемый отчет содержит набор данных, который используется для заполнения доступных значений параметра, и этот набор данных основан на запросе, который считывает строки из SomeTable .

Время ожидания LoadReport в конечном итоге истечет, и не останется никакой полезной информации, которая помогла бы вам выяснить, что произошло.

Возможные решения:

  • Измените отчет, чтобы выполнять «грязные чтения» на SomeTable
  • Измените базу данных на режим изоляции моментального снимка, чтобы избежать блокировки таблицы.

Я столкнулся с этим как с реальной производственной проблемой в системе, которая запускает отчеты по расписанию, и выполняемый отчет был отчетом «журнал запланированных отчетов».

Тонкость заключается в том, что LoadReport выполняет запросы — оглядываясь назад, очевидно, что он должен выполнять запросы, поскольку доступные значения для параметров содержатся в ExecutionInfo, который возвращается LoadReport.