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.