Delen via


Meerdere actieve resultatensets inschakelen

Mars (Multiple Active Result Sets) is een functie die werkt met SQL Server om de uitvoering van meerdere batches op één verbinding mogelijk te maken. Wanneer MARS is ingeschakeld voor gebruik met SQL Server, voegt elk opdrachtobject dat wordt gebruikt een sessie toe aan de verbinding.

Notitie

Eén MARS-sessie opent één logische verbinding voor MARS die moet worden gebruikt en vervolgens één logische verbinding voor elke actieve opdracht.

MARS in- en uitschakelen in de verbindingsreeks

Notitie

In de volgende verbindingsreeks wordt de voorbeelddatabase AdventureWorks gebruikt die is opgenomen in SQL Server. Bij de verbindingsreeks wordt ervan uitgegaan dat de database is geïnstalleerd op een server met de naam MSSQL1. Wijzig de verbindingsreeks indien nodig voor uw omgeving.

De MARS-functie is standaard uitgeschakeld. U kunt dit inschakelen door het "MultipleActiveResultSets=True" trefwoordpaar toe te voegen aan uw verbindingsreeks. True is de enige geldige waarde voor het inschakelen van MARS. In het volgende voorbeeld ziet u hoe u verbinding maakt met een exemplaar van SQL Server en hoe u opgeeft dat MARS moet worden ingeschakeld.

Dim connectionString As String = "..." & _
    "MultipleActiveResultSets=True"
string connectionString = "..." +
    "MultipleActiveResultSets=True";

U kunt MARS uitschakelen door het "MultipleActiveResultSets=False" trefwoordpaar toe te voegen aan uw verbindingsreeks. False is de enige geldige waarde voor het uitschakelen van MARS.

Speciale overwegingen bij het gebruik van MARS

Over het algemeen hoeven bestaande toepassingen niet te worden gewijzigd voor het gebruik van een MARS-verbinding. Als u echter MARS-functies in uw toepassingen wilt gebruiken, moet u de volgende speciale overwegingen begrijpen.

Interleaving van instructie

MARS-bewerkingen worden synchroon uitgevoerd op de server. Instructie-interleaving van SELECT- en BULK INSERT-instructies is toegestaan. DML-instructies (Data Manipulat Language) en DDL-instructies (Data Definition Language) worden echter atomisch uitgevoerd. Alle instructies die worden uitgevoerd terwijl een atomische batch wordt uitgevoerd, worden geblokkeerd. Parallelle uitvoering op de server is geen MARS-functie.

Als twee batches worden verzonden onder een MARS-verbinding, een daarvan met een SELECT-instructie, de andere met een DML-instructie, kan de DML beginnen met de uitvoering van de SELECT-instructie. De DML-instructie moet echter worden uitgevoerd tot voltooiing voordat de SELECT-instructie vooruitgang kan boeken. Als beide instructies worden uitgevoerd onder dezelfde transactie, zijn wijzigingen die zijn aangebracht door een DML-instructie nadat de SELECT-instructie is gestart, niet zichtbaar voor de leesbewerking.

Een WAITFOR-instructie in een SELECT-instructie levert de transactie niet op terwijl deze wacht, dat wil zeggen, totdat de eerste rij wordt geproduceerd. Dit betekent dat er geen andere batches binnen dezelfde verbinding kunnen worden uitgevoerd terwijl een WAITFOR-instructie wacht.

MARS-sessiecache

Wanneer een verbinding wordt geopend met MARS ingeschakeld, wordt er een logische sessie gemaakt, waardoor extra overhead wordt toegevoegd. Om de overhead te minimaliseren en de prestaties te verbeteren, slaat SqlClient de MARS-sessie in een verbinding in de cache op. De cache bevat maximaal 10 MARS-sessies. Deze waarde is niet door de gebruiker instelbaar. Als de sessielimiet is bereikt, wordt er een nieuwe sessie gemaakt. Er wordt geen fout gegenereerd. De cache en sessies in de cache zijn per verbinding; ze worden niet gedeeld tussen verbindingen. Wanneer een sessie wordt vrijgegeven, wordt deze geretourneerd naar de pool, tenzij de bovengrens van de pool is bereikt. Als de cachegroep vol is, wordt de sessie gesloten. MARS-sessies verlopen niet. Ze worden alleen opgeschoond wanneer het verbindingsobject wordt verwijderd. De MARS-sessiecache is niet vooraf geladen. De toepassing wordt geladen omdat er meer sessies nodig zijn voor de toepassing.

Veiligheid thread

MARS-bewerkingen zijn niet thread-safe.

Groepsgewijze verbinding

MARS-verbindingen worden gegroepeerd zoals elke andere verbinding. Als een toepassing twee verbindingen opent, één met MARS ingeschakeld en één met MARS uitgeschakeld, bevinden de twee verbindingen zich in afzonderlijke pools. Zie SQL Server Connection Pooling (ADO.NET) voor meer informatie.

SQL Server Batch-uitvoeringsomgeving

Wanneer een verbinding wordt geopend, wordt er een standaardomgeving gedefinieerd. Deze omgeving wordt vervolgens gekopieerd naar een logische MARS-sessie.

De omgeving voor batchuitvoering bevat de volgende onderdelen:

  • Opties instellen (bijvoorbeeld ANSI_NULLS, DATE_FORMAT, LANGUAGE, TEXTSIZE)

  • Beveiligingscontext (gebruikers-/toepassingsrol)

  • Databasecontext (huidige database)

  • Uitvoeringsstatusvariabelen (bijvoorbeeld @@ERROR, @@ROWCOUNT, @@FETCH_STATUS @@IDENTITY)

  • Tijdelijke tabellen op het hoogste niveau

Met MARS is een standaarduitvoeringsomgeving gekoppeld aan een verbinding. Elke nieuwe batch die onder een bepaalde verbinding wordt uitgevoerd, ontvangt een kopie van de standaardomgeving. Wanneer code wordt uitgevoerd onder een bepaalde batch, worden alle wijzigingen die in de omgeving zijn aangebracht, afgestemd op de specifieke batch. Zodra de uitvoering is voltooid, worden de uitvoeringsinstellingen gekopieerd naar de standaardomgeving. In het geval van één batch die meerdere opdrachten uitgeeft die opeenvolgend onder dezelfde transactie moeten worden uitgevoerd, zijn semantiek hetzelfde als die worden weergegeven door verbindingen met eerdere clients of servers.

Parallelle uitvoering

MARS is niet ontworpen om alle vereisten voor meerdere verbindingen in een toepassing te verwijderen. Als een toepassing echte parallelle uitvoering van opdrachten op een server nodig heeft, moeten meerdere verbindingen worden gebruikt.

Bekijk bijvoorbeeld het volgende scenario. Er worden twee opdrachtobjecten gemaakt, één voor het verwerken van een resultatenset en een andere voor het bijwerken van gegevens; ze delen een gemeenschappelijke verbinding via MARS. In dit scenario, de Transaction.Commit mislukt bij de update totdat alle resultaten zijn gelezen op het eerste opdrachtobject, wat de volgende uitzondering oplevert:

Bericht: Transactiecontext in gebruik door een andere sessie.

Bron: .NET SqlClient-gegevensprovider

Verwacht: (null)

Ontvangen: System.Data.SqlClient.SqlException

Er zijn drie opties voor het afhandelen van dit scenario:

  1. Start de transactie nadat de lezer is gemaakt, zodat deze geen deel uitmaakt van de transactie. Elke update wordt vervolgens een eigen transactie.

  2. Voer alle werkzaamheden door nadat de lezer is gesloten. Dit heeft het potentieel voor een aanzienlijke batch updates.

  3. Gebruik MARS niet; gebruik in plaats daarvan een afzonderlijke verbinding voor elk opdrachtobject, zoals u zou hebben vóór MARS.

MARS-ondersteuning detecteren

Een toepassing kan controleren op MARS-ondersteuning door de SqlConnection.ServerVersion waarde te lezen. Het belangrijkste getal moet 9 zijn voor SQL Server 2005 en 10 voor SQL Server 2008.

Zie ook