Share via


Använda transaktioner i en SQL-pool i Azure Synapse

Den här artikeln innehåller tips för att implementera transaktioner och utveckla lösningar i en SQL-pool.

Vad du kan förvänta dig

Som förväntat stöder SQL-poolen transaktioner som en del av arbetsbelastningen för informationslagret. Men för att säkerställa att SQL-poolen underhålls i stor skala är vissa funktioner begränsade jämfört med SQL Server. Den här artikeln belyser skillnaderna.

Transaktionsisoleringsnivåer

SQL-poolen implementerar ACID-transaktioner. Isoleringsnivån för transaktionsstödet är som standard READ UNCOMMITTED. Du kan ändra den till READ COMMITTED SNAPSHOT ISOLATION genom att aktivera alternativet READ_COMMITTED_SNAPSHOT databas för en användar-SQL-pool när den är ansluten till huvuddatabasen.

När det här alternativet är aktiverat körs alla transaktioner i den här databasen under READ COMMITTED SNAPSHOT ISOLATION och inställningen READ UNCOMMITTED på sessionsnivå kommer inte att respekteras. Mer information finns i ALTER DATABASE SET-alternativ (Transact-SQL).

Transaktionsstorlek

En enskild dataändringstransaktion är begränsad i storlek. Gränsen tillämpas per distribution. Därför kan den totala allokeringen beräknas genom att gränsen multipliceras med antalet fördelningar.

Om du vill beräkna det maximala antalet rader i transaktionen dividerar du distributionstaket med den totala storleken för varje rad. Överväg att ta en genomsnittlig kolumnlängd i stället för att använda den maximala storleken för kolumner med variabel längd.

I följande tabell har två antaganden gjorts:

  • En jämn fördelning av data har inträffat
  • Den genomsnittliga radlängden är 250 byte

Gen2

DWU Tak per distribution (GB) Antal distributioner MAXIMAL transaktionsstorlek (GB) Antal rader per distribution Maximalt antal rader per transaktion
DW100c 1 60 60 4,000,000 240,000,000
DW200c 1.5 60 90 6,000,000 360,000,000
DW300c 2.25 60 135 9,000,000 540,000,000
DW400c 3 60 180 12,000,000 720,000,000
DW500c 3.75 60 225 15,000,000 900,000,000
DW1000c 7.5 60 450 30,000,000 1,800,000,000
DW1500c 11.25 60 675 45,000,000 2,700,000,000
DW2000c 15 60 900 60,000,000 3,600,000,000
DW2500c 18.75 60 1125 75,000,000 4,500,000,000
DW3000c 22,5 60 1,350 90,000,000 5,400,000,000
DW5000c 37,5 60 2,250 150,000,000 9,000,000,000
DW6000c 45 60 2,700 180,000,000 10,800,000,000
DW7500c 56.25 60 3,375 225,000,000 13,500,000,000
DW10000c 75 60 4 500 300,000,000 18,000,000,000
DW15000c 112,5 60 6 750 450,000,000 27,000,000,000
DW30000c 225 60 13,500 900,000,000 54,000,000,000

Gen1

DWU Tak per distribution (GB) Antal distributioner MAXIMAL transaktionsstorlek (GB) Antal rader per distribution Maximalt antal rader per transaktion
DW100 1 60 60 4,000,000 240,000,000
DW200 1.5 60 90 6,000,000 360,000,000
DW300 2.25 60 135 9,000,000 540,000,000
DW400 3 60 180 12,000,000 720,000,000
DW500 3.75 60 225 15,000,000 900,000,000
DW600 4,5 60 270 18,000,000 1,080,000,000
DW1000 7.5 60 450 30,000,000 1,800,000,000
DW1200 9 60 540 36,000,000 2,160,000,000
DW1500 11.25 60 675 45,000,000 2,700,000,000
DW2000 15 60 900 60,000,000 3,600,000,000
DW3000 22,5 60 1,350 90,000,000 5,400,000,000
DW6000 45 60 2,700 180,000,000 10,800,000,000

Gränsen för transaktionsstorlek tillämpas per transaktion eller åtgärd. Den tillämpas inte på alla samtidiga transaktioner. Därför är varje transaktion tillåten att skriva den här mängden data till loggen.

Information om hur du optimerar och minimerar mängden data som skrivs till loggen finns i artikeln Metodtips för transaktioner .

Varning

Den maximala transaktionsstorleken kan bara uppnås för HASH- eller ROUND_ROBIN distribuerade tabeller där spridningen av data är jämn. Om transaktionen skriver data på ett skevt sätt till distributionerna kommer gränsen sannolikt att nås före den maximala transaktionsstorleken.

Transaktionstillstånd

SQL-poolen använder funktionen XACT_STATE() för att rapportera en misslyckad transaktion med värdet -2. Det här värdet innebär att transaktionen har misslyckats och endast har markerats för återställning.

Anteckning

Användningen av -2 av funktionen XACT_STATE för att ange en misslyckad transaktion representerar ett annat beteende än SQL Server. SQL Server använder värdet -1 för att representera en transaktion som inte kan användas. SQL Server kan tolerera vissa fel i en transaktion utan att den behöver markeras som ogenomförbar. Till exempel SELECT 1/0 skulle orsaka ett fel men inte tvinga en transaktion till ett tillstånd som inte kan tas med.

SQL Server tillåter även läsningar i den ej inkombara transaktionen. Du kan dock inte göra detta i SQL-poolen. Om ett fel inträffar i en SQL-pooltransaktion kommer det automatiskt att ange tillståndet -2 och du kommer inte att kunna göra några ytterligare select-instruktioner förrän -instruktionen har återställts.

Därför är det viktigt att kontrollera att programkoden använder XACT_STATE() eftersom du kan behöva göra kodändringar.

I SQL Server kan du till exempel se en transaktion som ser ut så här:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

Föregående kod ger följande felmeddelande:

Msg 111233, Level 16, State 1, Line 1 111233; Den aktuella transaktionen har avbrutits och eventuella väntande ändringar har återställts. Orsaken till det här problemet är att en transaktion i ett återställningstillstånd inte uttryckligen återställs före en DDL-, DML- eller SELECT-instruktion.

Du får inte utdata från ERROR_*-funktionerna.

I SQL-poolen måste koden ändras något:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;
    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

Det förväntade beteendet observeras nu. Felet i transaktionen hanteras och funktionerna ERROR_* anger värden som förväntat.

Allt som har ändrats är att återställningen av transaktionen måste ske innan felinformationen lästes i CATCH-blocket.

funktionen Error_Line()

Det är också värt att notera att SQL-poolen inte implementerar eller stöder funktionen ERROR_LINE(). Om du har detta i koden måste du ta bort den för att vara kompatibel med SQL-poolen.

Använd frågeetiketter i koden i stället för att implementera motsvarande funktioner. Mer information finns i artikeln ETIKETT .

Använda THROW och RAISERROR

THROW är den modernare implementeringen för att skapa undantag i SQL-poolen, men RAISERROR stöds också. Det finns dock några skillnader som är värda att uppmärksamma.

  • Användardefinierade felmeddelanden får inte ligga inom intervallet 100 000–150 000 för THROW
  • RAISERROR-felmeddelanden är fasta vid 50 000
  • Användning av sys.messages stöds inte

Begränsningar

SQL-poolen har några andra begränsningar som gäller transaktioner.

Det här är skillnaderna:

  • Inga distribuerade transaktioner
  • Inga kapslade transaktioner tillåts
  • Inga lagringspunkter tillåts
  • Inga namngivna transaktioner
  • Inga markerade transaktioner
  • Inget stöd för DDL, till exempel CREATE TABLE i en användardefinierad transaktion

Nästa steg

Mer information om hur du optimerar transaktioner finns i Metodtips för transaktioner. Mer information om andra metodtips för SQL-pooler finns i Metodtips för SQL-pool.