2010-02-20 3 views
4

내 서버 응용 프로그램에서 DB (SQL Server)를 사용하고 싶지만 가장 좋은 방법은 확실하지 않습니다. 스레드 풀에 요청한 클라이언트가 있으므로 처리가 비동기입니다. 모든 요청은 대개 DB를 읽거나 쓰는 것이 필요하므로 연결을 만들고 쿼리를 실행 한 다음 결과를 반환하는 정적 메서드를 생각하고있었습니다. 나는 열리고 닫는 연결이 너무 느리지 않고 어떤 연결 한계에 도달 할 수 없었는지 단 두려운가요? 좋은 접근 방법인가요?다중 스레드 서버 응용 프로그램에서 SQL DB에 대한 액세스

답변

0

아무도 연결 풀링에 대해 언급하지 않았습니다. 요청 수가 많을 것으로 생각되면 왜 풀 크기가 25 (임의의 숫자, 쏘지 않음)로 설정되고 최대 풀 크기가 200으로 설정되는 풀을 설정하지 말아야합니다. 이것은 연결 시도 횟수를 줄이고 연결 핸들이 누출되지 않으면 (즉, 발생하지 않도록주의를 기울여야하는 사항), 항상 연결 대기 상태가 유지되는지 확인하십시오. 연결 풀링에 대한 참조 문서 : http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx 또 다른 부작용, 왜 코드에 연결 문자열이 있어야합니까? 유지 보수를 위해 web.config 또는 app.config에 설정하십시오. 그런 일을하는 코드를 "고쳐야"하고 그런 일을 담당하는 프로그래머에게 항상 맹세코 충고했습니다.

+0

감사합니다. 또한 연결 열기 (문자열에 지정된 풀링 포함)가있는 정적 메서드로도 충분합니까? 그런 다음이 정적 메서드를 다른 스레드에서 호출합니다. – Thomas

+0

예, 상당히 좋습니다. 풀링 방법은 매우 쉬운 데이터 액세스를 위해 entlib와 함께 사용하는 방법입니다. 나는 이것이 또한 당신이 들여다 봐야 할 무엇인가라고 제안한다. 따라서 코드에있는 것보다 데이터 액세스가 훨씬 쉬워집니다. – chiefbrownbotom

0

나는 당신과 똑같은 문제가있었습니다. 내가 멀티 스레드를 만들기 시작한 거대한 응용 프로그램이 있었어. 하나의 연결을 열고 재사용하는 것 이상의 이점은 새로운 연결이 요청에 따라 생성되므로 다른 스레드가 데이터를 마칠 때까지 기다릴 필요가 없으며 SQL 연결이 느슨한 경우 (예 : 네트워크가 1 초 또는 2 초 동안 다운 될 때 발생할 수 있습니다.) 어쨌든 쿼리를 제출하기 전에 연결이 열려 있는지 항상 확인해야합니다.

이것은 MS SQL에서 데이터베이스 행을 가져 오는 코드이지만 다른 것들은 정확히 같은 방식으로 수행되어야합니다. sqlConnectOneTime (문자열 varSqlConnectionDetails)에는 연결이 없을 때 null을 반환하는 결함이 있으므로 필요에 따라 약간의 수정이 필요하거나 sql이 연결을 설정하지 못하면 쿼리가 실패합니다. 당신은 그냥

public const string sqlDataConnectionDetails = "Data Source=SQLSERVER\\SQLEXPRESS;Initial Cata...."; 

    public static string sqlGetDatabaseRows(string varDefinedConnection) { 
     string varRows = ""; 
     const string preparedCommand = @" 
        SELECT SUM(row_count) AS 'Rows' 
        FROM sys.dm_db_partition_stats 
        WHERE index_id IN (0,1) 
        AND OBJECTPROPERTY([object_id], 'IsMsShipped') = 0;"; 
     using (var varConnection = Locale.sqlConnectOneTime(varDefinedConnection)) 
     using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) 
     using (var sqlQueryResult = sqlQuery.ExecuteReader()) 
      while (sqlQueryResult.Read()) { 
       varRows = sqlQueryResult["Rows"].ToString(); 
      } 
     return varRows; 
    } 


    public static SqlConnection sqlConnectOneTime(string varSqlConnectionDetails) { 
     SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails); 
     try { 
      sqlConnection.Open(); 
     } catch (Exception e) { 
      MessageBox.Show("Błąd połączenia z serwerem SQL." + Environment.NewLine + Environment.NewLine + "Błąd: " + Environment.NewLine + e, "Błąd połączenia"); 
     } 
     if (sqlConnection.State == ConnectionState.Open) { 
      return sqlConnection; 
     } 
     return null; 
    } 

요약 :-) 당신을 위해 도움이 될 것입니다 희망 :-)이 처리하는 적절한 코드를 추가해야합니다 : SQL 서버의 ConnectionDetails와

정의 하나 개의 글로벌 변수

하나 전역 메소드 (null을 처리해야 함)

읽기/쓰기/업데이트 방법이 완료되면 연결, sql 쿼리 및 모든 것을 처리하기 위해 using을 사용하십시오.

+0

이것은 실제로 작동하지 않습니다 ... 연결을 사용하려고하면 시간이 sedcond입니다. 상단의 끝에 {} 블록을 사용하여 폐기되었으므로 사용할 수 없습니다. – Rob

+0

사용하는대로 작동합니다 . sqlGetDatabaseRows를 2 초마다 호출하고 설계된대로 작동합니다. 두 번째 연결을 사용하고 싶지 않습니다. 내가 방법을 시작, 그것은 SQL에 연결하고 그것은 SQL 쿼리와 함께 완료되면 연결을 닫고 모든 것을 처분. 다음에 데이터베이스를 조회하려면 다시 연결해야합니다. SQL에 연결해야하는 각 메서드에서 새 연결을 엽니 다. – MadBoy

+0

@Rob 왜 내 생각이 나쁘다고 생각하는지 설명 할 수 있습니까? http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx 문서에서 제안 된대로 Using using 내부 연결을 엽니 다. 풀에 반환되고 필요할 경우 다시 사용할 수 있습니다. – MadBoy

0

당신에게 맞는 답변을 제공하는 것이 유용 할 것입니다. 귀하는 귀하의 서버 응용 프로그램이 어떤 수준의 부하를 기대하고 있습니까?.

위의 질문에 대한 답변이 거의없는 경우 대답은 걱정할 필요가 없다는 것입니다. ADO.net/Sql Server는 각 "var c = new SqlConnection (connectionString)"호출에서 연결을 만드는 오버 헤드 중 일부를 제거하는 연결 풀링을 제공합니다.

+0

또한 쿼리 인수가있는 정적 메서드를 가질 수 있으며 연결이 풀되기 때문에 다른 스레드에서 호출 할 수 있습니까? – Thomas

1

IMHO 가장 좋은 방법은 ADO.NET 연결 풀링 메커니즘을 사용하고 데이터베이스 연결을 수동으로 처리하지 않는 것입니다.다음과 같이 데이터 액세스 방법을 작성하십시오.

public void SomeMethod() 
{ 
    using (var connection = new SqlConnection(connectionString)) 
    using (var command = connection.CreateCommand()) 
    { 
     connection.Open(); 
     command.CommandText = "SELECT Field1 FROM Table1"; 
     using (var reader = command.ExecuteReader()) 
     { 
      while(reader.Read()) 
      { 
       // do something with the results 
      } 
     } 
    } 
} 

그런 다음이 메소드를 원하는 위치에서 호출하고 정적으로 만들고 스레드에서 호출 할 수 있습니다. 연결에서 Dispose을 호출한다고해서 실제로 연결이 닫히지는 않습니다. 다시 사용할 수 있도록 연결 풀로 반환합니다.

관련 문제