Använda transaktioner med dedikerad SQL-pool i Azure Synapse Analytics

Tips för att implementera transaktioner med dedikerad SQL-pool i Azure Synapse Analytics för att utveckla lösningar.

Vad du kan förvänta dig

Som förväntat har den dedikerade SQL-poolen stöd för transaktioner som en del av arbetsbelastningen för informationslagret. För att säkerställa att prestandan för den dedikerade SQL-poolen bibehålls i stor skala är vissa funktioner dock begränsade jämfört med SQL Server. Den här artikeln belyser skillnaderna och listar de andra.

Transaktionsisoleringsnivåer

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

När det ä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 ALTERNATIV FÖR ALTER DATABASE SET (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 multiplicera gränsen med antalet fördelningar.

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

I tabellen nedan har följande 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 MAX transaktionsstorlek (GB) # 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 MAX transaktionsstorlek (GB) # 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

Transaktionsstorleksgränsen tillämpas per transaktion eller åtgärd. Den tillämpas inte för alla samtidiga transaktioner. Därför tillåts varje transaktion 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

Den dedikerade 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 misslyckades och markeras endast 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 nås. SQL Server kan tolerera vissa fel i en transaktion utan att den behöver markeras som okommentabel. 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 icke-bindande transaktionen. Den dedikerade SQL-poolen låter dig dock inte göra detta. Om ett fel inträffar i en dedikerad 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. Det är därför 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. Orsak: En transaktion i ett återställningstillstånd återställdes inte uttryckligen före en DDL-, DML- eller SELECT-instruktion.

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

I en dedikerad SQL-pool 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_* ger 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 den dedikerade SQL-poolen inte implementerar eller stöder funktionen ERROR_LINE(). Om du har den här funktionen i koden måste du ta bort den för att vara kompatibel med en dedikerad SQL-pool. Använd frågeetiketter i koden i stället för att implementera motsvarande funktioner. Mer information finns i artikeln ETIKETT .

Användning av THROW och RAISERROR

THROW är den modernare implementeringen för att skapa undantag i en dedikerad SQL-pool, 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 i 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

Den dedikerade 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 sparpunkter 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. Ytterligare metodtipsguider finns också för dedikerad SQL-pool och serverlös SQL-pool.