Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Vonatkozik a következőkre:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analitikai Platform System (PDW)
SQL adatbázis a Microsoft Fabric-ben
Az SQL Server 2005 (9.x) bevezette a több aktív eredményhalmazt (MARS) támogatását azokban az alkalmazásokban, amelyek hozzáférnek az adatbázis motorhoz. Az SQL Server korábbi verzióiban az adatbázis-alkalmazások nem tudtak több aktív utasítást fenntartani egy kapcsolaton. Az SQL Server alapértelmezett eredményhalmazainak használatakor az alkalmazásnak egy tételből feldolgoznia vagy törölnie kellett az összes eredményhalmazt, mielőtt bármely másik kötetet végrehajthatott volna azon a kapcsolaton. Az SQL Server 2005 (9.x) új kapcsolati attribútumot vezetett be, amely lehetővé teszi, hogy az alkalmazások kapcsolatonként több függőben lévő kérést is tartalmazzanak, különösen egy kapcsolatonként több aktív alapértelmezett eredményhalmazt is legyen.
A MARS egyszerűsíti az alkalmazástervezést az alábbi új képességekkel:
Az alkalmazások több alapértelmezett eredményhalmazt is megnyithatnak, és ezek alapján össze tudnak olvasni.
Az alkalmazások más utasításokat is végrehajthatnak (például INSERT, UPDATE, DELETE és tárolt eljáráshívásokat), miközben az alapértelmezett eredményhalmazok nyitva vannak.
A MARS-t használó pályázatok az alábbi irányelveket hasznosnak találják:
Az alapértelmezett eredményhalmazokat rövid vagy rövid eredményhalmazokhoz kell használni, amelyeket egyetlen SQL utasítás (SELECT, DML kimeneteltel, receive, read text és így tovább) generáltak.
A szerverkurzorokat hosszabb életű vagy nagy eredményhalmazokhoz kell használni, amelyeket egyetlen SQL utasítás generál.
Eljárási kéréseknél mindig olvasd fel az eredmények végéig, függetlenül attól, hogy visszaadnak-e eredményt vagy sem, illetve azoknál a tételeknél, amelyek több eredményt adnak.
Ahol lehetséges, használj API-hívásokat a kapcsolati tulajdonságok megváltoztatására és a tranzakciók kezelésére a Transact-SQL utasítások helyett.
A MARS-ban a session keretében történő személyazonyítás tilos, amíg párhuzamosan zajlanak a sorozatok.
Megjegyzés:
Alapértelmezés szerint a MARS funkciók nincsenek engedélyezve. Ahhoz, hogy a MARS használata az SQL Serverhez való OLE DB Driver for SQL Server csatlakozás közben kifejezetten engedélyezni kell egy kapcsolati láncon belül. További információért lásd az OLE DB Driver for SQL Server szekciót, amely később ebben a témában található.
Az OLE DB Driver for SQL Server nem korlátozza az aktív utasítások számát egy kapcsolaton.
A tipikus alkalmazások, amelyeknek nem kell egyszerre több multiplex-utasítási tételt vagy tárolt eljárást futtatniuk, profitálhatnak a MARS-ból anélkül, hogy érteniük, hogyan valósítják meg a MARS-t. Azonban a bonyolultabb követelményeket igénylő alkalmazásoknak ezt figyelembe kell venniük.
A MARS lehetővé teszi több kérés interleave-alapú végrehajtását egyetlen kapcsolaton belül. Vagyis lehetővé teszi egy batch futtatását, és a végrehajtás során más kérések futtatását is lehetővé teszi. Fontos azonban megjegyezni, hogy a MARS interleaving szempontjából definiálható, nem pedig párhuzamos végrehajtás szempontjából.
A MARS infrastruktúra lehetővé teszi, hogy több tétel interleaved módon hajtson végre, bár a végrehajtás csak jól meghatározott pontokon lehet váltani. Ezen felül a legtöbb állításnak atomiszerűen kell futnia egy adagon belül. Azok a mondatok, amelyek visszaadják a sorokat a kliensnek, amelyeket néha hozási pontoknak neveznek, engedélyezettek a végrehajtás interleave-e futtatása a befejezés előtt, miközben sorokat küldenek a kliensnek, például:
SELECT
FETCH
RECEIVE
Minden más utasításnak, amelyet egy tárolt eljárás vagy kötet részeként hajtanak végre, befejezésig kell futnia, mielőtt a végrehajtást más MARS kérésekre lehetne áthelyezni.
A batchesek végrehajtásának pontos módját számos tényező befolyásolja, és nehéz megjósolni, hogy pontosan milyen sorrendben hajtják végre több tételből származó parancsokat, amelyek hozampontokat tartalmaznak. Ügyelj arra, hogy elkerüld a nem kívánt mellékhatásokat, amelyek az ilyen összetett adagok interleave-es végrehajtása miatt járnak.
Kerüld el a problémákat azzal, hogy API-hívásokat használsz Transact-SQL utasítások helyett a kapcsolati állapot (SET, USE) és tranzakciók (BEGIN TRAN, COMMIT, ROLLBACK) kezelésére azzal, hogy ezeket a utasításokat nem vonjuk be többmondatos kötetekbe, amelyek szintén hozampontokat tartalmaznak, és az ilyen tételek futtatását soriázzák az összes eredmény fogyasztásával vagy törlésével.
Megjegyzés:
Egy kötet vagy tárolt eljárás, amely kézi vagy implicit tranzakciót indít, amikor a MARS engedélyezett, a tranzakciót a batch kilépése előtt kell teljesítenie. Ha nem, az SQL Server visszavonja az összes tranzakció által végrehajtott változtatást, amikor a batch véget ér. Az ilyen tranzakciót az SQL Server csomag-alapú tranzakcióként kezeli. Ez egy új típusú tranzakció, amelyet az SQL Server 2005 (9.x) vezetett be, hogy lehetővé tegye a meglévő, jól viselkedő tárolt eljárások használatát, amikor a MARS be van kapcsolva. További információért a batch-scoped tranzakciókról lásd: Tranzakciós kimutatások (Transact-SQL).
Az ADO-ból készült MARS használatának példáját lásd: Using ADO with OLE DB Driver for SQL Server.
In-Memory OLTP (memórián belüli OLTP)
A memórián belüli OLTP támogatja a MARS-t lekérdezések és natívan lefordított tárolt eljárások használatával. A MARS lehetővé teszi, hogy több lekérdezésből is kérjen adatokat anélkül, hogy minden eredményhalmazt teljesen le kellene kérni, mielőtt sorokat küldene egy új eredményhalmazból. Ahhoz, hogy több nyílt eredményhalmazból sikeresen olvass, MARS-kompatibilis kapcsolatot kell használni.
A MARS alapértelmezés szerint le van tiltva, így kifejezetten be kell kapcsolnod egy kapcsolati lánchoz hozzáadva MultipleActiveResultSets=True . Az alábbi példa bemutatja, hogyan lehet csatlakozni egy SQL Server példányhoz, és meghatározni, hogy a MARS engedélyezve legyen:
Data Source=MSSQL; Initial Catalog=AdventureWorks; Integrated Security=SSPI; MultipleActiveResultSets=True
A MARS In-Memory OLTP-vel lényegében ugyanaz, mint a MARS az SQL motor többi részében. Az alábbiakban felsoroljuk a különbségeket a MARS használatakor memóriaoptimalizált táblákban és natívan fordított tárolt eljárásokban.
MARS és memóriaoptimalizált táblázatok
Az alábbiakban a lemezalapú és memóriaoptimalizált táblázatok közötti különbségek MARS-kompatibilis kapcsolat esetén:
Két állítás módosíthatja az adatokat ugyanabban a célobjektumban, de ha mindkettő megpróbálja módosítani ugyanazt a rekordot, egy írás-írás ütközés az új művelet sikertelenségét okozza. Azonban, ha mindkét művelet eltérő rekordokat módosít, a műveletek sikeresek lesznek.
Minden utasítás SNAPSHOT izoláció alatt fut, így az új műveletek nem láthatják a meglévő utasítások által végrehajtott változtatásokat. Még ha az egyidejű utasításokat ugyanazon tranzakció alatt is hajtják végre, az SQL motor minden utasításhoz egymástól elszigetelt batch-scoped tranzakciókat hoz létre. Azonban a batch-scoped tranzakciók továbbra is összekötöttek, így az egyik batch-scoped tranzakció visszafordítása befolyásolja a többi kötet ugyanabban a kötetben.
A DDL műveletek nem engedélyezettek a felhasználói tranzakciókban, így azonnal meghibásodnak.
MARS és natívan fordított tárolt eljárások
A natívan fordított tárolt eljárások MARS-engedélyezett kapcsolatokban futhatnak, és csak akkor engedhetnek végrehajtást egy másik utasításhoz, ha találkozik egy engedelmes ponttal. Egy yield point esetén SELECT utasítás szükséges, amely az egyetlen utasítás egy natívan lefordított tárolt eljárásban, amely képes egy másik utasítás futtatását eredményezni. Ha egy SELECT utasítás nincs jelen az eljárásban, akkor nem ad meg, és a befejezésig fut, mielőtt más utasítások kezdődnének.
MARS és memóriában lévő OLTP tranzakciók
Az állítások és atomblokkok által végrehajtott változtatások, amelyek egymástól elkülönítenek. Például, ha egy állítás vagy atomblokk változtatást hajt végre, majd egy másik utasítás végrehajtását eredményezi, az új utasítás nem látja az első állítás által végrehajtott változtatásokat. Ezen felül, amikor az első állítás folytatódik, nem lát más állítások által végrehajtott változtatásokat. A kijelentések csak azokat a változtatásokat látják, amelyeket a kijelentés kezdete előtt befejeznek és elköteleznek.
Egy új felhasználói tranzakciót indíthatunk el a jelenlegi felhasználói tranzakción belül a BEGIN TRANSACTION utasítással – ez csak interop módban támogatott, így a BEGIN TRANSACTION csak egy T-SQL utasításból hívható meg, nem pedig egy natívan lefordított tárolt eljárásból. Létrehozhatsz mentési pontot egy tranzakcióban SAVE TRANSACTION vagy egy API hívással a tranzakcióhoz. Mented(save_point_name) a mentési ponthoz való visszaguruláshoz. Ez a funkció csak T-SQL utasításokból engedélyezett, nem a natívan lefordított tárolt eljárásokból.
MARS és oszlopáruház indexek
Az SQL Server (2016-tól kezdve) támogatja a MARS-t columnstore indexekkel. SQL Server 2014 a MARS-t használja csak olvasható kapcsolatokhoz táblákhoz, amelyek oszloptároló indexkel rendelkeznek. Az SQL Server 2014 azonban nem támogatja a MARS-t egy oszloptároló indexű táblán végzett egyidejű adatkezelő nyelvi (DML) műveletekhez. Amikor ez megtörténik, az SQL Server megszünteti a kapcsolatokat és megszakítja a tranzakciókat. Az SQL Server 2012 csak olvasható oszlopos indexeket tartalmaz, és a MARS nem vonatkozik rájuk.
OLE DB-illesztő az SQL Serverhez
Az SQL Server OLE DB Driver támogatja a MARS-t a SSPROP_INIT_MARSCONNECTION adatforrás inicializációs tulajdonságának hozzáadásával, amely a DBPROPSET_SQLSERVERDBINIT tulajdonsághalmazban van megvalósítva. Ezen felül egy új kapcsolati lánc kulcsszó, a MarsConn is hozzáadódott. Elfogadja az igaz vagy hamis értékeket; A hamisság az alapértelmezett.
Az adatforrás tulajdonság DBPROP_MULTIPLECONNECTIONS alapértelmezés szerint VARIANT_TRUE. Ez azt jelenti, hogy a szolgáltató több kapcsolatot is létrehoz, hogy több párhuzamos parancs- és sorkészletobjektumot is támogatjon. Amikor a MARS engedélyezett, az OLE DB Driver SQL Serverhez több parancs- és sorkészletobjektumot is támogat egyetlen kapcsolaton, így MULTIPLE_CONNECTIONS alapértelmezetten VARIANT_FALSE-re van állítva.
További információért a DBPROPSET_SQLSERVERDBINIT tulajdonsághalmazban végrehajtott fejlesztésekről lásd: Initializációs és engedélyezési tulajdonságok.
OLE DB Driver for SQL Server Example
Ebben a példában egy adatforrás objektumot az SQL Server OLE DB Driver segítségével hoznak létre, és a MARS a DBPROPSET_SQLSERVERDBINIT tulajdonság halmazával van engedélyezve, mielőtt a session objektum létrejött.
#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);