Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platí na:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytický platformový systém (PDW)
SQL databáze v Microsoft Fabric
SQL Server 2005 (9.x) zavedl podporu více aktivních sad výsledků (MARS) v aplikacích přistupujících k databázovému enginu. V dřívějších verzích SQL Serveru nemohly databázové aplikace udržovat více aktivních příkazů na spojení. Při použití výchozích sad výsledků SQL Serveru musela aplikace zpracovat nebo zrušit všechny sady výsledků z jedné dávky, než mohla spustit jinou dávku na tomto připojení. SQL Server 2005 (9.x) zavedl nový atribut připojení, který umožňuje aplikacím mít více než jeden čekající požadavek na jedno připojení, a zejména více než jednu aktivní výchozí sadu výsledků na jedno připojení.
MARS zjednodušuje návrh aplikací o následující nové funkce:
Aplikace mohou mít otevřené více výchozích sad výsledků a mohou z nich prokládat čtení.
Aplikace mohou provádět jiné příkazy (například INSERT, UPDATE, DELETE a uložené procedurální volání), zatímco výchozí sady výsledků jsou otevřené.
Aplikace využívající MARS najdou přínosné následující pokyny:
Výchozí sady výsledků by měly být použity pro krátkodobé nebo krátkodobé sady výsledků generované jednotlivými SQL příkazy (SELECT, DML s OUTPUT, RECEIVE, READ TEXT a podobně).
Serverové kurzory by měly být používány pro delší životnost nebo velké sady výsledků generované jednotlivými SQL příkazy.
Vždy čtěte výsledky až do konce u procedurálních požadavků bez ohledu na to, zda výsledky vracejí nebo ne, a u šarží, které vracejí více výsledků.
Kde je to možné, používejte API volání ke změně vlastností spojení a spravujte transakce před Transact-SQL příkazy.
V MARS je simulace simulace v rámci session zakázána, dokud běží současné dávky.
Poznámka:
Ve výchozím nastavení není funkčnost MARS zapnutá. Pro použití MARS při připojení ke SQL Serveru pomocí OLE DB Driver pro SQL Server musíte jej konkrétně povolit v rámci řetězce připojení. Pro více informací viz sekce OLE DB Driver for SQL Server později v tomto tématu.
OLE DB Driver pro SQL Server neomezuje počet aktivních příkazů na spojení.
Typické aplikace, které nemusí mít více než jednu vícevýrazovou dávku nebo uloženou proceduru vykonávanou současně, budou mít z MARS prospěch, aniž by musely rozumět implementaci MARS. Nicméně aplikace s náročnějšími požadavky musí toto zohlednit.
MARS umožňuje prokládání více požadavků v rámci jednoho spojení. To znamená, že umožňuje spustit dávku a během jejího vykonávání umožňuje vykonat i další požadavky. Je však třeba poznamenat, že MARS je definován z hlediska prokládání, nikoli paralelního provádění.
Infrastruktura MARS umožňuje provádění více dávek v prokládaném režimu, i když provádění lze přepínat pouze na dobře definovaných místech. Navíc většina tvrzení musí běžet atomicky v rámci dávky. Příkazy, které vracejí řádky klientovi, někdy označované jako yield points, mohou provádět prokládání před dokončením, zatímco řádky jsou klientu odesílány, například:
SELECT
FETCH
RECEIVE
Jakékoliv další příkazy, které jsou vykonávány jako součást uložené procedury nebo dávky, musí být dokončeny před tím, než lze převést na jiné MARS požadavky.
Přesný způsob, jakým batch prokládá prokládání, ovlivňuje řada faktorů a je obtížné předpovědět přesné pořadí, v jakém budou vykonány příkazy z více dávek obsahujících body výtěku. Buďte opatrní, abyste se vyhnuli nežádoucím vedlejším účinkům při prokládání takto složitých várek.
Vyhněte se problémům použitím volání API místo Transact-SQL příkazů pro správu stavu spojení (SET, USE) a transakcí (BEGIN TRAN, COMMIT, ROLLBACK) tím, že tyto příkazy nezahrňte do vícepříkazových dávek, které také obsahují výnosové body, a serializace provádění těchto dávek tím, že všechny výsledky spotřebováváte nebo rušíte.
Poznámka:
Dávková nebo uložená procedura, která zahájí manuální nebo implicitní transakci při zapnutí MARS, musí transakci dokončit před ukončením dávky. Pokud ne, SQL Server po dokončení batch stáhne všechny změny provedené transakcí zpět. Taková transakce je spravována SQL Serverem jako batch-scope transakce. Toto je nový typ transakce zavedený v SQL Server 2005 (9.x), který umožňuje použití existujících dobře fungujících uložených procedur při povolení MARS. Pro více informací o dávkově řízených transakcích viz Výpisy transakcí (Transact-SQL).
Pro příklad použití MARS od ADO viz Použití ADO s OLE DB Driver pro SQL Server.
Technologie zpracování OLTP v paměti (In-Memory OLTP)
OLTP v paměti podporuje MARS pomocí dotazů a nativně zkompilovaných uložených procedur. MARS umožňuje požadavek na data z více dotazů bez nutnosti úplně získat každou sadu výsledků před odesláním požadavku na načtení řádků z nové sady výsledků. Pro úspěšné čtení z více otevřených sad výsledků musíte použít připojení s podporou MARS.
MARS je ve výchozím nastavení zakázán, takže jej musíte explicitně povolit přidáním MultipleActiveResultSets=True do řetězce připojení. Následující příklad ukazuje, jak se připojit k instanci SQL Serveru a specifikovat, že je povolen MARS:
Data Source=MSSQL; Initial Catalog=AdventureWorks; Integrated Security=SSPI; MultipleActiveResultSets=True
MARS s In-Memory OLTP je v podstatě stejný jako MARS v ostatních částech SQL enginu. Následuje seznam rozdílů při použití MARS v tabulkách optimalizovaných pro paměť a nativně kompilovaných uložených procedurách.
MARS a tabulky optimalizované pro paměť
Následují rozdíly mezi tabulkami založenými na disku a optimalizovanými tabulkami pro paměť při použití připojení s podporou MARS:
Dva příkazy mohou upravovat data ve stejném cílovém objektu, ale pokud se oba pokusí upravit stejný záznam, konflikt zápisu a zápisu způsobí selhání nové operace. Pokud však obě operace upraví různé záznamy, operace uspějí.
Každý příkaz běží v izolaci SNAPSHOT, takže nové operace nemohou vidět změny provedené stávajícími příkazy. I když jsou souběžné příkazy vykonány pod stejnou transakcí, SQL engine vytváří pro každý příkaz dávkově zaměřené transakce, které jsou od sebe odděleny. Nicméně transakce s dávkovým rozsahem jsou stále propojené, takže návrat jedné batch-scope transakce ovlivňuje i další v téže dávce.
DDL operace nejsou povoleny v uživatelských transakcích, takže okamžitě selžou.
MARS a nativně kompilované uložené procedury
Nativně kompilované uložené procedury mohou běžet v MARS podporovaných spojeních a mohou vést k vykonání jiného příkazu pouze při dosažení bodu výtěku. Yield point vyžaduje příkaz SELECT, což je jediný příkaz v nativně kompilované uložené procedurě, který může vést k vykonání jiného příkazu. Pokud v postupu není přítomen příkaz SELECT, který nevrátí, dokončí ho dříve, než začnou ostatní příkazy.
MARS a transakce OLTP v paměti
Změny vytvořené výroky a atomickými bloky, které jsou prokládány, jsou od sebe izolované. Například pokud jeden příkaz nebo atomický blok provede změny a pak vykoná jiný příkaz, nový příkaz neuvidí změny provedené prvním příkazem. Navíc, když první příkaz obnoví vykonání, neuvidí žádné změny vykonané jinými příkazy. Výpisy uvidí pouze změny, které jsou dokončeny a potvrzeny před začátkem prohlášení.
Novou uživatelskou transakci lze zahájit v rámci aktuální uživatelské transakce pomocí příkazu BEGIN TRANSACTION – to je podporováno pouze v interop režimu, takže BEGIN TRANSACTION lze volat pouze z T-SQL příkazu, nikoli z nativně kompilované uložené procedury. Uložený bod v transakci můžete vytvořit pomocí SAVE TRANSACTION nebo API call to transaction. Uložit(save_point_name) pro návrat k uloženému bodu. Tato funkce je také povolena pouze z T-SQL příkazů, nikoli z nativně zkompilovaných uložených procedur.
MARS a indexy columnstore
SQL Server (od roku 2016) podporuje MARS s indexy columnstore. SQL Server 2014 používá MARS pro připojení pouze pro čtení k tabulkám s indexem columnstore. SQL Server 2014 však nepodporuje MARS pro operace souběžného jazyka pro manipulaci s daty (DML) na tabulce s indexem columnstore. Když k tomu dojde, SQL Server ukončí připojení a transakce zruší. SQL Server 2012 má indexy columnstore pouze pro čtení a MARS se na ně nevztahuje.
Ovladač OLE DB pro SQL Server
Ovladač OLE DB pro SQL Server podporuje MARS přidáním inicializace zdrojů dat SSPROP_INIT_MARSCONNECTION, která je implementována v sadě DBPROPSET_SQLSERVERDBINIT vlastností. Navíc bylo přidáno nové klíčové slovo pro spojovací řetězce, MarsConn. Přijímá pravdivé nebo nepravdivé hodnoty; False je výchozí.
Vlastnost zdroj dat DBPROP_MULTIPLECONNECTIONS výchozí VARIANT_TRUE. To znamená, že poskytovatel vytvoří více připojení, aby podpořil více současných příkazových a řádkových objektů. Když je MARS povolen, OLE DB Driver for SQL Server může podporovat více objektů příkazů a řádků na jednom připojení, takže MULTIPLE_CONNECTIONS je ve výchozím nastavení nastaveno na VARIANT_FALSE.
Pro více informací o vylepšeních DBPROPSET_SQLSERVERDBINIT vlastnostní sadě viz Inicializace a autorizační vlastnosti.
Příklad OLE DB Driver for SQL Server
V tomto příkladu je objekt datového zdroje vytvořen pomocí OLE DB Driver pro SQL Server a MARS je povolen pomocí sady DBPROPSET_SQLSERVERDBINIT před vytvořením objektu relace.
#include <msoledbsql.h>
IDBInitialize *pIDBInitialize = NULL;
IDBCreateSession *pIDBCreateSession = NULL;
IDBProperties *pIDBProperties = NULL;
// Create the data source object.
hr = CoCreateInstance(CLSID_MSOLEDBSQL, 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);