Condividi tramite


Uso di più set di risultati attivi (MARS)

SQL Server 2005 ha introdotto il supporto per più set di risultati attivi (MARS) nelle applicazioni che accedono al motore di database. Nelle versioni precedenti di SQL Server, le applicazioni di database non potevano mantenere più istruzioni attive in una connessione. Quando si usano i set di risultati predefiniti di SQL Server, l'applicazione doveva elaborare o annullare tutti i set di risultati da un batch prima di poter eseguire qualsiasi altro batch in tale connessione. SQL Server 2005 ha introdotto un nuovo attributo di connessione che consente alle applicazioni di avere più di una richiesta in sospeso per ogni connessione e, in particolare, di avere più di un set di risultati predefinito attivo per ogni connessione.

MARS semplifica la progettazione delle applicazioni con le nuove funzionalità seguenti:

  • Le applicazioni possono avere più set di risultati predefiniti aperti e possono interleaverne la lettura.

  • Le applicazioni possono eseguire altre istruzioni, ad esempio INSERT, UPDATE, DELETE e stored procedure, mentre i set di risultati predefiniti sono aperti.

Le applicazioni che usano MARS troveranno utili le linee guida seguenti:

  • I set di risultati predefiniti devono essere usati per set di risultati di breve durata o brevi generati da singole istruzioni SQL (SELECT, DML con OUTPUT, RECEIVE, READ TEXT e così via).

  • I cursori del server devono essere usati per set di risultati di lunga durata o di grandi dimensioni generati da singole istruzioni SQL.

  • Leggere sempre alla fine dei risultati per le richieste procedurali indipendentemente dal fatto che restituiscano risultati o meno e per i batch che restituiscono più risultati.

  • Laddove possibile, usare le chiamate API per modificare le proprietà di connessione e gestire le transazioni in preferenza per Transact-SQL istruzioni.

  • In MARS la rappresentazione con ambito sessione non è consentita durante l'esecuzione di batch simultanei.

Annotazioni

Per impostazione predefinita, la funzionalità MARS non è abilitata. Per usare MARS per la connessione a SQL Server con SQL Server Native Client, è necessario abilitarlo in modo specifico all'interno di una stringa di connessione. Per altre informazioni, vedere le sezioni del provider OLE DB di SQL Server Native Client e del driver ODBC di SQL Server Native Client, più avanti in questo argomento.

SQL Server Native Client non limita il numero di istruzioni attive in una connessione.

Le applicazioni tipiche che non devono avere più di un singolo batch multistatement o stored procedure in esecuzione contemporaneamente trarranno vantaggio da MARS senza dover comprendere come viene implementato MARS. Tuttavia, le applicazioni con requisiti più complessi devono tenere conto di questo.

MARS consente l'esecuzione interleaved di più richieste all'interno di una singola connessione. Ciò significa che consente l'esecuzione di un batch e, all'interno dell'esecuzione, consente l'esecuzione di altre richieste. Si noti, tuttavia, che MARS è definito in termini di interleaving, non in termini di esecuzione parallela.

L'infrastruttura MARS consente l'esecuzione di più batch in modo interleaved, anche se l'esecuzione può essere cambiata solo in punti ben definiti. Inoltre, la maggior parte delle istruzioni deve essere eseguita in modo atomico all'interno di un batch. Le istruzioni che restituiscono righe al client, a volte definite punti di resa, possono interleavere l'esecuzione prima del completamento mentre le righe vengono inviate al client, ad esempio:

  • SELEZIONA

  • PRENDERE

  • RICEVERE

Tutte le altre istruzioni eseguite come parte di una stored procedure o di un batch devono essere eseguite fino al completamento prima che l'esecuzione possa essere passata ad altre richieste MARS.

Il modo esatto in cui l'esecuzione interleave batch è influenzata da diversi fattori ed è difficile prevedere la sequenza esatta in cui verranno eseguiti i comandi di più batch che contengono punti di resa. Prestare attenzione a evitare effetti collaterali indesiderati a causa dell'esecuzione interleaved di tali batch complessi.

Evitare problemi tramite chiamate API anziché Transact-SQL istruzioni per gestire lo stato di connessione (SET, USE) e le transazioni (BEGIN TRAN, COMMIT, ROLLBACK) senza includere queste istruzioni in batch con più istruzioni che contengono anche punti di resa e serializzando l'esecuzione di tali batch utilizzando o annullando tutti i risultati.

Annotazioni

Una stored procedure o batch che avvia una transazione manuale o implicita quando MARS è abilitato deve completare la transazione prima dell'uscita del batch. In caso contrario, SQL Server esegue il rollback di tutte le modifiche apportate dalla transazione al termine del batch. Tale transazione viene gestita da SQL Server come transazione con ambito batch. Si tratta di un nuovo tipo di transazione introdotto in SQL Server 2005 per consentire l'uso di stored procedure ben strutturate esistenti quando MARS è abilitato. Per altre informazioni sulle transazioni con ambito batch, vedere Transaction Statements (Transact-SQL).

Per un esempio di uso di MARS da ADO, vedere Uso di ADO con SQL Server Native Client.

Provider OLE DB di SQL Server Native Client

Il provider OLE DB di SQL Server Native Client supporta MARS tramite l'aggiunta della proprietà di inizializzazione dell'origine dati SSPROP_INIT_MARSCONNECTION, implementata nel set di proprietà DBPROPSET_SQLSERVERDBINIT. Inoltre, è stata aggiunta una nuova parola chiave della stringa di connessione, MarsConn, . Accetta o false valoritrue; false è l'impostazione predefinita.

Per impostazione predefinita, la proprietà dell'origine dati DBPROP_MULTIPLECONNECTIONS viene VARIANT_TRUE. Ciò significa che il provider genererà più connessioni per supportare più oggetti comando e set di righe simultanei. Quando MARS è abilitato, SQL Server Native Client può supportare più oggetti comando e set di righe in una singola connessione, pertanto MULTIPLE_CONNECTIONS è impostato su VARIANT_FALSE per impostazione predefinita.

Per altre informazioni sui miglioramenti apportati al set di proprietà DBPROPSET_SQLSERVERDBINIT, vedere Inizializzazione e proprietà di autorizzazione.

Esempio di provider OLE DB di SQL Server Native Client

In questo esempio viene creato un oggetto origine dati usando il provider SQL Server Native OLE DB e MARS viene abilitato usando la proprietà DBPROPSET_SQLSERVERDBINIT impostata prima della creazione dell'oggetto sessione.

#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);  

Driver ODBC di SQL Server Native Client

Il driver ODBC di SQL Server Native Client supporta MARS tramite aggiunte alle funzioni SQLSetConnectAttr e SQLGetConnectAttr . SQL_COPT_SS_MARS_ENABLED è stato aggiunto per accettare SQL_MARS_ENABLED_YES o SQL_MARS_ENABLED_NO, con SQL_MARS_ENABLED_NO come impostazione predefinita. Inoltre, è stata aggiunta una nuova parola chiave della stringa di connessione, Mars_Connection, . Accetta valori "sì" o "no" ; "no" è l'impostazione predefinita.

Esempio di driver ODBC di SQL Server Native Client

In questo esempio, la funzione SQLSetConnectAttr viene usata per abilitare MARS prima di chiamare la funzione SQLDriverConnect per connettere il database. Una volta stabilita la connessione, vengono chiamate due funzioni SQLExecDirect per creare due set di risultati separati nella stessa connessione.

#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);  

Vedere anche

Funzionalità di SQL Server Native Client
Uso dei set di risultati predefiniti di SQL Server