다음을 통해 공유


다중 활성 결과 집합(MARS) 사용

SQL Server 2005는 데이터베이스 엔진에 액세스하는 애플리케이션에서 MARS(다중 활성 결과 집합)에 대한 지원을 도입했습니다. 이전 버전의 SQL Server에서는 데이터베이스 애플리케이션이 연결에서 여러 활성 문을 유지할 수 없었습니다. SQL Server 기본 결과 집합을 사용하는 경우 애플리케이션은 해당 연결에서 다른 일괄 처리를 실행하기 전에 한 일괄 처리의 모든 결과 집합을 처리하거나 취소해야 했습니다. SQL Server 2005에는 애플리케이션이 연결당 둘 이상의 보류 중인 요청을 가질 수 있고, 특히 연결당 둘 이상의 활성 기본 결과 집합을 가질 수 있는 새로운 연결 특성이 도입되었습니다.

MARS는 다음과 같은 새로운 기능을 사용하여 애플리케이션 디자인을 간소화합니다.

  • 애플리케이션에는 여러 기본 결과 집합이 열려 있고 읽기를 인터리브할 수 있습니다.

  • 애플리케이션은 기본 결과 집합이 열려 있는 동안 다른 문(예: INSERT, UPDATE, DELETE 및 저장 프로시저 호출)을 실행할 수 있습니다.

MARS를 사용하는 애플리케이션은 다음과 같은 지침이 도움이 됩니다.

  • 기본 결과 집합은 단일 SQL 문(SELECT, OUTPUT이 있는 DML, RECEIVE, READ TEXT 등)에서 생성되는 수명이 짧거나 짧은 결과 집합에 사용해야 합니다.

  • 서버 커서는 단일 SQL 문에 의해 생성된 수명이 길거나 큰 결과 집합에 사용해야 합니다.

  • 결과를 반환하는지 여부에 관계없이 절차적 요청과 여러 결과를 반환하는 일괄 처리의 경우 항상 결과의 끝까지 읽습니다.

  • 가능한 경우 API 호출을 사용하여 연결 속성을 변경하고 Transact-SQL 문에 대한 기본 설정으로 트랜잭션을 관리합니다.

  • MARS에서는 동시 일괄 처리가 실행되는 동안 세션 범위 가장이 금지됩니다.

비고

기본적으로 MARS 기능은 사용하도록 설정되지 않습니다. SQL Server Native Client를 사용하여 SQL Server에 연결할 때 MARS를 사용하려면 특히 연결 문자열 내에서 MARS를 사용하도록 설정해야 합니다. 자세한 내용은 이 항목의 뒷부분에 나오는 SQL Server Native Client OLE DB 공급자 및 SQL Server Native Client ODBC 드라이버 섹션을 참조하세요.

SQL Server Native Client는 연결에 대한 활성 문의 수를 제한하지 않습니다.

단일 다중 상태 일괄 처리 또는 저장 프로시저를 동시에 실행할 필요가 없는 일반적인 애플리케이션은 MARS가 구현되는 방식을 이해할 필요 없이 MARS의 이점을 누릴 수 있습니다. 그러나 더 복잡한 요구 사항이 있는 애플리케이션은 이를 고려해야 합니다.

MARS를 사용하면 단일 연결 내에서 여러 요청을 인터리브할 수 있습니다. 즉, 일괄 처리를 실행할 수 있으며 실행 내에서 다른 요청을 실행할 수 있습니다. 그러나 MARS는 병렬 실행이 아니라 인터리빙 측면에서 정의됩니다.

MARS 인프라를 사용하면 여러 배치를 인터리브 방식으로 실행할 수 있지만 실행은 잘 정의된 지점에서만 전환할 수 있습니다. 또한 대부분의 문은 일괄 처리 내에서 원자성으로 실행되어야 합니다. 행을 클라이언트에 반환하는 문(경우에 따라 수율 지점이라고도 함)은 행을 클라이언트로 보내는 동안 완료되기 전에 실행을 인터리브할 수 있습니다. 예를 들면 다음과 같습니다.

  • 선택

  • 가져오기

  • 받다

저장 프로시저 또는 일괄 처리의 일부로 실행되는 다른 문은 실행을 다른 MARS 요청으로 전환하기 전에 완료까지 실행해야 합니다.

일괄 처리 인터리브 실행이 여러 요인의 영향을 받는 정확한 방식이며, 수율 지점을 포함하는 여러 일괄 처리의 명령이 실행되는 정확한 순서를 예측하기는 어렵습니다. 이러한 복잡한 일괄 처리의 인터리브 실행으로 인해 원치 않는 부작용을 피해야 합니다.

Transact-SQL 문이 아닌 API 호출을 사용하여 연결 상태(SET, USE) 및 트랜잭션(BEGIN TRAN, COMMIT, ROLLBACK)을 관리하는 경우 이러한 문을 수율 지점이 포함된 다중 문 일괄 처리에 포함하지 않고 모든 결과를 사용하거나 취소하여 이러한 일괄 처리의 실행을 직렬화하여 문제를 방지합니다.

비고

MARS를 사용할 때 수동 또는 암시적 트랜잭션을 시작하는 일괄 처리 또는 저장 프로시저는 일괄 처리가 종료되기 전에 트랜잭션을 완료해야 합니다. 그렇지 않은 경우 SQL Server는 일괄 처리가 완료되면 트랜잭션에 의해 변경된 모든 변경 내용을 롤백합니다. 이러한 트랜잭션은 SQL Server에서 일괄 처리 범위 트랜잭션으로 관리됩니다. MARS를 사용할 때 기존 잘 동작하는 저장 프로시저를 사용할 수 있도록 SQL Server 2005에 도입된 새로운 유형의 트랜잭션입니다. 일괄 처리 범위 트랜잭션에 대한 자세한 내용은 트랜잭션 문(Transact-SQL)을 참조하세요.

ADO에서 MARS를 사용하는 예제는 SQL Server Native Client에서 ADO 사용을 참조하세요.

SQL Server Native Client OLE DB 공급자

SQL Server Native Client OLE DB 공급자는 DBPROPSET_SQLSERVERDBINIT 속성 집합에서 구현되는 SSPROP_INIT_MARSCONNECTION 데이터 원본 초기화 속성을 추가하여 MARS를 지원합니다. 또한 추가된 새 연결 문자열 키워드 MarsConn도 추가되었습니다. 허용 true 또는 falsefalse 입니다. 기본값입니다.

데이터 원본 속성 DBPROP_MULTIPLECONNECTIONS 기본값은 VARIANT_TRUE. 즉, 공급자는 여러 동시 명령 및 행 집합 개체를 지원하기 위해 여러 연결을 생성합니다. MARS를 사용하는 경우 SQL Server Native Client는 단일 연결에서 여러 명령 및 행 집합 개체를 지원할 수 있으므로 기본적으로 MULTIPLE_CONNECTIONS VARIANT_FALSE 설정됩니다.

DBPROPSET_SQLSERVERDBINIT 속성 집합의 향상된 기능과 대한 자세한 내용은 초기화 및 권한 부여 속성을 참조하세요.

SQL Server Native Client OLE DB 공급자 예제

이 예제에서는 SQL Server 네이티브 OLE DB 공급자를 사용하여 데이터 원본 개체를 만들고 MARS는 세션 개체를 만들기 전에 설정된 DBPROPSET_SQLSERVERDBINIT 속성을 사용하여 사용하도록 설정됩니다.

#include <sqlncli.h>  
  
IDBInitialize *pIDBInitialize = NULL;  
IDBCreateSession *pIDBCreateSession = NULL;  
IDBProperties *pIDBProperties = NULL;  
  
// Create the data source object.  
hr = CoCreateInstance(CLSID_SQLNCLI10, NULL,  
   CLSCTX_INPROC_SERVER,  
   IID_IDBInitialize,   
    (void**)&pIDBInitialize);  
  
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties);  
  
// Set the MARS property.  
DBPROP rgPropMARS;  
  
// The following is necessary since MARS is off by default.  
rgPropMARS.dwPropertyID = SSPROP_INIT_MARSCONNECTION;  
rgPropMARS.dwOptions = DBPROPOPTIONS_REQUIRED;  
rgPropMARS.dwStatus = DBPROPSTATUS_OK;  
rgPropMARS.colid = DB_NULLID;  
V_VT(&(rgPropMARS.vValue)) = VT_BOOL;  
V_BOOL(&(rgPropMARS.vValue)) = VARIANT_TRUE;  
  
// Create the structure containing the properties.  
DBPROPSET PropSet;  
PropSet.rgProperties = &rgPropMARS;  
PropSet.cProperties = 1;  
PropSet.guidPropertySet = DBPROPSET_SQLSERVERDBINIT;  
  
// Get an IDBProperties pointer and set the initialization properties.  
pIDBProperties->SetProperties(1, &PropSet);  
pIDBProperties->Release();  
  
// Initialize the data source object.  
hr = pIDBInitialize->Initialize();  
  
//Create a session object from a data source object.  
IOpenRowset * pIOpenRowset = NULL;  
hr = IDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession));  
hr = pIDBCreateSession->CreateSession(  
   NULL,             // pUnkOuter  
   IID_IOpenRowset,  // riid  
  &pIOpenRowset ));  // ppSession  
  
// Create a rowset with a firehose mode cursor.  
IRowset *pIRowset = NULL;  
DBPROP rgRowsetProperties[2];  
  
// To get a firehose mode cursor request a   
// forward only read only rowset.  
rgRowsetProperties[0].dwPropertyID = DBPROP_IRowsetLocate;  
rgRowsetProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[0].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[0].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[0].vValue));  
rgRowsetProperties[0].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[0].vValue.boolVal = VARIANT_FALSE;  
  
rgRowsetProperties[1].dwPropertyID = DBPROP_IRowsetChange;  
rgRowsetProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[1].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[1].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[1].vValue));  
rgRowsetProperties[1].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[1].vValue.boolVal = VARIANT_FALSE;  
  
DBPROPSET rgRowsetPropSet[1];  
rgRowsetPropSet[0].rgProperties = rgRowsetProperties  
rgRowsetPropSet[0].cProperties = 2  
rgRowsetPropSet[0].guidPropertySet = DBPROPSET_ROWSET;  
  
hr = pIOpenRowset->OpenRowset (NULL,  
   &TableID,  
   NULL,  
   IID_IRowset,  
   1,  
   rgRowsetPropSet  
   (IUnknown**)&pIRowset);  

SQL Server Native Client ODBC 드라이버

SQL Server Native Client ODBC 드라이버는 SQLSetConnectAttr 및 SQLGetConnectAttr 함수를 추가하여 MARS를 지원합니다. SQL_MARS_ENABLED_NO 기본값인 SQL_MARS_ENABLED_YES 또는 SQL_MARS_ENABLED_NO 허용하도록 SQL_COPT_SS_MARS_ENABLED 추가되었습니다. 또한 추가된 새 연결 문자열 키워드 Mars_Connection도 추가되었습니다. "yes" 또는 "no" 값을 허용합니다. "no"가 기본값입니다.

SQL Server Native Client ODBC 드라이버 예제

이 예제에서는 SQLDriverConnect 함수를 호출하여 데이터베이스를 연결하기 전에 MARS를 사용하도록 설정하는 데 SQLSetConnectAttr 함수를 사용합니다. 연결이 완료되면 두 개의 SQLExecDirect 함수가 호출되어 동일한 연결에 두 개의 별도 결과 집합을 만듭니다.

#include <sqlncli.h>  
  
SQLSetConnectAttr(hdbc, SQL_COPT_SS_MARS_ENABLED, SQL_MARS_ENABLED_YES, SQL_IS_UINTEGER);  
SQLDriverConnect(hdbc, hwnd,   
   "DRIVER=SQL Server Native Client 10.0;  
   SERVER=(local);trusted_connection=yes;", SQL_NTS, szOutConn,   
   MAX_CONN_OUT, &cbOutConn, SQL_DRIVER_COMPLETE);  
  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt1);  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt2);  
  
// The 2nd execute would have failed with connection busy error if  
// MARS were not enabled.  
SQLExecDirect(hstmt1, L"SELECT * FROM Authors", SQL_NTS);  
SQLExecDirect(hstmt2, L"SELECT * FROM Titles", SQL_NTS);  
  
// Result set processing can interleave.  
SQLFetch(hstmt1);  
SQLFetch(hstmt2);  

또한 참조하십시오

SQL Server Native Client 기능
SQL Server 기본 결과 집합 사용