SqlDataAdapter.Fill (DataTable)을 사용하여 테이블에서 간단한 SELECT를 수행하는 프로세스가 포함 된 콘솔 일괄 처리 응용 프로그램이 있습니다.채우기 (DataTable) 테스트에 성공했으며 응답이 없습니다.
private DataTable getMyTable(string conStr)
{
DataTable tb = new DataTable();
StringBuilder bSql = new StringBuilder();
bSql.AppendLine("SELECT * FROM MyDB.dbo.MyTable");
bSql.AppendLine("WHERE LEN(IdString) > 0");
try
{
string connStr = ConfigurationManager.ConnectionStrings[conStr].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlDataAdapter adpt = new SqlDataAdapter(bSql.ToString(), conn))
{
adpt.Fill(tb);
}
}
return tb;
}
catch (SqlException sx)
{
throw sx;
}
catch (Exception ex)
{
throw ex;
}
}
이 방법은 동 기적으로 실행되고, 테스트의 많은 개월 동안 여러 테스트 환경에서 성공적으로 실행 된 - 모두 명령 줄에서 시작 또는 AutoSys 작업의 제어하에 시작했을 때.
그러나 프로덕션 환경으로 이동하면 프로세스가 멈추었습니다. Fill 메서드를 사용하면 거의 알 수 있습니다. 더욱이 시간이 초과되는 대신 새로운 요청 스레드가 생성되기 시작했으며 몇 시간 만 지나면 응용 프로그램 서버에서 5GB 이상의 메모리가 소모되었습니다. 이것은 다른 활성 응용 프로그램에 영향을 미치므로 매우 인기가 없었습니다. 예외가 발생하지 않았습니다.
연결 문자열은 마치 평범한 바닐라처럼 보입니다.
"data source=SERVER\INSTANCE;initial catalog=MyDB;integrated security=True;"
사과는 내가 (이 아래 AutoSys 작업이 실행 된)는 SQL DBA 아래보고 있지만, 우리는 SQL 서버에 넣어 추적을했을 때, 그것은 응용 프로그램 ID를 보였다 무엇에 대한 잘못된 용어를 사용하는 경우 받아 들여지고 유효한 로그인으로. 그런 다음 서버는 SELECT 쿼리를 처리하는 것으로 보입니다. 그러나 결코 응답을 반환하지 않았습니다. 대신, 그것은 "명령 대기 중"상태가되었습니다. 요청 스레드가 몇 분 동안 열린 상태로 유지 된 다음 사라졌습니다.
DBA에 따르면 교착 상태의 징후는 보이지 않지만 차단 여부를 실시간으로 모니터링해야합니다.
프로덕션 환경에서만 발생합니다. 테스트 환경에서 SQL Server는 항상 1 초 이내에 응답했습니다.
AutoSys Application ID는 새로운 것이 아닙니다. 다른 SQL Server와 수년간 사용되어 왔으며 아무런 문제가 없었습니다. DBA는 해당 ID로 로그인 한 프로덕션 SQL 서버에서 SELECT 쿼리를 수동으로 실행하여 정상적으로 응답했습니다.
프로덕션 환경이 아닌 환경에서 문제를 재현 할 수 없으며 서버 관리자가 대기 상태가 아닌 프로덕션 환경에서 프로세스를 종료하기를 주저합니다. 우리의 보안 요구 사항은 서버 로그 및 프로세스를 볼 수있는 나의 액세스를 제한하며, 보통 나를 위해 다른 전문가를 고용해야합니다.
조만간이 문제를 해결해야합니다. 현재보고있는 데이터의 양은 단지 몇 줄에 불과하지만 향후 몇 개월 동안 증가 할 것입니다. 무슨 일이 일어나고 있는지, 응용 프로그램 서버와 SQL 서버 사이의 통신 및/또는 보안이 관련되어 있다는 것이 가장 좋습니다.
추가 아이디어 나 조사 할 항목을 환영합니다. 모두에게 감사드립니다.
대용량 데이터베이스의 경우 VS에서 쿼리를 완료하는 데 오랜 시간이 걸릴 수 있습니다. 걸기 방지 BackGroundWorker를 사용하여 작업을 수행합니다. SQL Server와 함께 제공되는 명령 줄 실행 파일 인 cmd.exe를 사용하여 쿼리를 수행하고 결과가 포함 된 csv 파일을 생성합니다. 그런 다음 VS 응용 프로그램으로 결과를 읽습니다. cmd.exe를 C#에서 backgbroundworker 내부의 프로세스 클래스를 사용하여 실행합니다. – jdweng
@ jdweng : 나는 그것이 좋은 지적이라고 생각한다. 그것은 하나의 간단한 선택 진술은 SQL 명령 줄 도구에서 가능성을 제외, 그 응용 프로그램 내부에 뭔가 잘못 실행하는 경우. 테이블이 얼마나 큽니까? TOP 1000으로 선택을 실행하여 결과 데이터가 예상대로 작동하는지 확인할 수 있습니다. 처음에는 csv에 데이터를 쓰는 것이 이상하게 들리지만 실제로는 큰 데이터를 사용하는 것이 좋습니다. –
내 응용 프로그램에서 sqlcmd.exe는 10GB 데이터베이스에서 30 분 이상을 사용하고있었습니다. C#에서 쿼리로 시간이 걸렸습니다. 그리고 쿼리가 실행되는 동안 응용 프로그램에 대한 내 윈도우가 멈췄다. sqlcmd.exe의 결과를 C#으로 가져 오는 유일한 방법은 csv 파일을 사용하는 것입니다. – jdweng