Sdílet prostřednictvím


Použití transakcí ve fondu SQL v Azure Synapse

Tento článek obsahuje tipy pro implementaci transakcí a vývoj řešení ve fondu SQL.

Co očekávat

Jak byste očekávali, fond SQL podporuje transakce jako součást úlohy datového skladu. Pokud ale chcete zajistit, aby se fond SQL udržoval ve velkém měřítku, jsou některé funkce ve srovnání s SQL Server omezené. Tento článek upozorňuje na rozdíly.

Úrovně izolace transakcí

Fond SQL implementuje transakce ACID. Úroveň izolace transakční podpory je ve výchozím nastavení READ UNCOMMITTED. Pokud ho chcete změnit na IZOLACI SNÍMKŮ POTVRZENÉ ČTENÍ, zapněte možnost READ_COMMITTED_SNAPSHOT databáze pro fond SQL uživatele při připojení k hlavní databázi.

Po povolení se všechny transakce v této databázi spouštějí v části IZOLACE SNÍMKŮ POTVRZENÉ PRO ČTENÍ a nastavení READ UNCOMMITTED na úrovni relace nebude dodrženo. Podrobnosti najdete v části ALTER DATABASE SET options (Transact-SQL).

Velikost transakce

Velikost jedné transakce úpravy dat je omezená. Limit se použije na distribuci. Proto je možné celkovou alokaci vypočítat vynásobením limitu počtem rozdělení.

Chcete-li odhadnout maximální počet řádků v transakci, vydělte distribuční limit celkovou velikostí každého řádku. U sloupců s proměnlivou délkou zvažte průměrnou délku sloupce místo maximální velikosti.

V následující tabulce byly provedeny dva předpoklady:

  • Došlo k rovnoměrné distribuci dat.
  • Průměrná délka řádku je 250 bajtů.

Gen2

DWU Cap per distribution (GB) Počet rozdělení Maximální velikost transakce (GB) Počet řádků na distribuci Maximální počet řádků na transakci
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 Limit na distribuci (GB) Počet rozdělení MAXIMÁLNÍ velikost transakce (GB) Počet řádků na distribuci Maximální počet řádků na transakci
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

Limit velikosti transakce se použije na transakci nebo operaci. Nepoužívá se u všech souběžných transakcí. Proto je každá transakce povolena k zápisu tohoto množství dat do protokolu.

Pokud chcete optimalizovat a minimalizovat množství dat zapsaných do protokolu, projděte si článek Osvědčené postupy transakcí .

Upozornění

Maximální velikosti transakce lze dosáhnout pouze u hodnot HASH nebo ROUND_ROBIN distribuovaných tabulek, kde je rozložení dat rovnoměrné. Pokud transakce zapisuje data nerovnoměrně do distribucí, je pravděpodobné, že limitu bude dosaženo před maximální velikostí transakce.

Stav transakce

Fond SQL používá funkci XACT_STATE() k hlášení neúspěšné transakce s hodnotou -2. Tato hodnota znamená, že transakce selhala a je označena pouze pro vrácení zpět.

Poznámka

Použití -2 XACT_STATE funkce k označení neúspěšné transakce představuje jiné chování SQL Server. SQL Server použije hodnotu -1 k reprezentaci nepotvitelné transakce. SQL Server může tolerovat některé chyby uvnitř transakce, aniž by musely být označeny jako nekommitovatelné. Může například způsobit chybu, SELECT 1/0 ale ne vynutit transakci do nekommitovatelného stavu.

SQL Server také povoluje čtení v nepovolitelné transakci. Fond SQL to ale neumožňuje. Pokud dojde k chybě uvnitř transakce fondu SQL, automaticky přejde do stavu -2 a nebudete moct provádět žádné další příkazy pro výběr, dokud se příkaz nevrátí zpět.

Proto je důležité zkontrolovat kód aplikace, abyste zjistili, jestli používá XACT_STATE(), protože možná budete muset kód upravit.

Například v SQL Server se může zobrazit transakce, která vypadá takto:

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;

Předchozí kód zobrazí následující chybovou zprávu:

msg 111233, úroveň 16, stav 1, řádek 1 111233; Aktuální transakce byla přerušena a všechny čekající změny byly vráceny zpět. Příčinou tohoto problému je, že transakce ve stavu jen pro vrácení zpět není explicitně vrácena zpět před příkazem DDL, DML nebo SELECT.

Nezobrazí se výstup funkcí ERROR_*.

Ve fondu SQL je potřeba kód mírně změnit:

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;

Nyní je pozorováno očekávané chování. Chyba v transakci je spravována a funkce ERROR_* poskytují hodnoty podle očekávání.

Jediné, co se změnilo, je, že vrácení zpět transakce muselo proběhnout před přečtením informací o chybě v bloku CATCH.

Error_Line()

Je také vhodné poznamenat, že fond SQL neimplementuje ani nepodporuje funkci ERROR_LINE(). Pokud ho máte v kódu, musíte ho odebrat, aby byl kompatibilní s fondem SQL.

Místo toho použijte popisky dotazů v kódu k implementaci ekvivalentních funkcí. Další podrobnosti najdete v článku LABEL .

Použití funkce THROW a RAISERROR

THROW je modernější implementace pro vyvolání výjimek ve fondu SQL, ale podporuje se také FUNKCE RAISERROR. Existuje několik rozdílů, které stojí za pozornost.

  • Uživatelsky definovaná čísla chybových zpráv nemohou být v rozsahu 100 000 až 150 000 pro throw
  • Chybové zprávy RAISERROR jsou opravené na 50 000
  • Použití sys.messages není podporováno.

Omezení

Fond SQL má několik dalších omezení, která se vztahují k transakcím.

Jsou to tyto:

  • Žádné distribuované transakce
  • Nejsou povoleny žádné vnořené transakce.
  • Nejsou povoleny žádné body pro ukládání.
  • Žádné pojmenované transakce
  • Žádné označené transakce
  • Žádná podpora pro DDL, například CREATE TABLE uvnitř uživatelem definované transakce

Další kroky

Další informace o optimalizaci transakcí najdete v tématu Osvědčené postupy pro transakce. Další informace o dalších osvědčených postupech pro fond SQL najdete v tématu Osvědčené postupy pro fond SQL.