#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.