Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Suggerimenti per l'implementazione di transazioni con pool SQL dedicato in Azure Synapse Analytics per lo sviluppo di soluzioni.
Cosa aspettarsi
Come previsto, il pool SQL dedicato supporta le transazioni come parte del carico di lavoro del data warehouse. Tuttavia, per garantire che le prestazioni del pool SQL dedicato vengano mantenute su larga scala, alcune funzionalità sono limitate rispetto a SQL Server. In questo articolo vengono evidenziate le differenze e vengono elencate le altre.
Livelli di isolamento delle transazioni
Il pool SQL dedicato implementa le transazioni ACID. Il livello di isolamento del supporto transazionale è impostato di default su READ UNCOMMITTED. È possibile modificarlo in READ COMMITTED SNAPSHOT ISOLATION attivando l'opzione di database READ_COMMITTED_SNAPSHOT per un database utente quando si è connessi al database master.
Dopo l'abilitazione, tutte le transazioni in questo database vengono eseguite in READ COMMITTED SNAPSHOT ISOLATION e l'impostazione di READ UNCOMMITTED a livello di sessione non verrà rispettata. Per informazioni dettagliate, vedere le opzioni ALTER DATABASE SET (Transact-SQL).
Dimensioni delle transazioni
Una singola transazione di modifica dei dati è limitata in dimensioni. Il limite viene applicato per distribuzione. Di conseguenza, l'allocazione totale può essere calcolata moltiplicando il limite per il conteggio delle distribuzioni.
Per approssimare il numero massimo di righe nella transazione, dividere il limite di distribuzione in base alle dimensioni totali di ogni riga. Per le colonne a lunghezza variabile, prendere in considerazione la lunghezza media di una colonna anziché usare le dimensioni massime.
Nella tabella seguente sono stati fatti i presupposti seguenti:
- Si è verificata una distribuzione uniforme dei dati
- La lunghezza media della riga è di 250 byte
Seconda generazione
| DWU | Limite per distribuzione (GB) | Numero di distribuzioni | Dimensioni massime delle transazioni (GB) | Numero di righe per distribuzione | Numero massimo di righe per transazione |
|---|---|---|---|---|---|
| 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 |
Prima generazione
| DWU | Limite per distribuzione (GB) | Numero di distribuzioni | Dimensioni massime delle transazioni (GB) | Numero di righe per distribuzione | Numero massimo di righe per transazione |
|---|---|---|---|---|---|
| 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 |
Il limite di dimensioni delle transazioni viene applicato per transazione o operazione. Non viene applicato in tutte le transazioni simultanee. Pertanto, ogni transazione è autorizzata a scrivere questa quantità di dati nel log.
Per ottimizzare e ridurre al minimo la quantità di dati scritti nel log, vedere l'articolo Procedure consigliate per le transazioni .
Avviso
Le dimensioni massime delle transazioni possono essere ottenute solo per HASH o ROUND_ROBIN tabelle distribuite in cui la distribuzione dei dati è pari. Se la transazione scrive dati in modo asimmetrico nelle distribuzioni, è probabile che il limite venga raggiunto prima delle dimensioni massime della transazione.
Stato della transazione
Il pool SQL dedicato usa la funzione XACT_STATE() per segnalare una transazione non riuscita usando il valore -2. Questo valore indica che la transazione non è riuscita ed è contrassegnata solo per il rollback.
Annotazioni
L'uso di -2 dalla funzione XACT_STATE per indicare una transazione non riuscita rappresenta un comportamento diverso per SQL Server. SQL Server usa il valore -1 per rappresentare una transazione non modificabile. SQL Server può tollerare alcuni errori all'interno di una transazione senza che sia necessario contrassegnarlo come non modificabile. Ad esempio SELECT 1/0 , potrebbe causare un errore ma non forzare una transazione in uno stato non modificabile. SQL Server consente anche le letture nella transazione non committabile. Tuttavia, il pool SQL dedicato non consente di eseguire questa operazione. Se si verifica un errore all'interno di una transazione del pool SQL dedicato, verrà automaticamente immesso lo stato -2 e non sarà possibile eseguire ulteriori istruzioni select finché non viene eseguito il rollback dell'istruzione. È quindi importante verificare che il codice dell'applicazione verifichi se usa XACT_STATE() perché potrebbe essere necessario apportare modifiche al codice.
Ad esempio, in SQL Server potrebbe essere visualizzata una transazione simile alla seguente:
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;
Il codice precedente visualizza il messaggio di errore seguente:
Messaggio 111233, livello 16, stato 1, riga 1 111233; La transazione corrente è stata interrotta ed è stato eseguito il rollback delle modifiche in sospeso. Causa: non è stato eseguito il rollback in modo esplicito di una transazione in uno stato di solo rollback prima di un'istruzione DDL, DML o SELECT.
Non si otterrà l'output delle funzioni ERROR_*.
Nel pool SQL dedicato, il codice deve essere leggermente modificato:
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;
Viene ora osservato il comportamento previsto. L'errore nella transazione viene gestito e le funzioni ERROR_* forniscono valori come previsto.
Ciò dimostra che il ROLLBACK della transazione doveva essere eseguito prima della lettura delle informazioni sull'errore nel blocco CATCH.
funzione Error_Line()
Vale anche la pena notare che il pool SQL dedicato non implementa o supporta la funzione ERROR_LINE(). Se si dispone di questa funzione nel codice, è necessario rimuoverla in modo che sia conforme al pool SQL dedicato. Usare invece le etichette di query nel codice per implementare funzionalità equivalenti. Per altre informazioni, vedere l'articolo LABEL .
Uso di THROW e RAISERROR
THROW è l'implementazione più moderna per generare eccezioni nel pool SQL dedicato, ma è supportato anche RAISERROR. Esistono tuttavia alcune differenze che vale la pena prestare attenzione.
- I numeri di messaggi di errore definiti dall'utente non possono essere compresi nell'intervallo da 100.000 a 150.000 per THROW
- I messaggi di errore RAISERROR sono fissati a 50.000
- L'uso di sys.messages non è supportato
Limitazioni
Il pool SQL dedicato prevede alcune altre restrizioni correlate alle transazioni. Sono i seguenti:
- Nessuna transazione distribuita
- Non sono consentite transazioni annidate
- Nessun punto di salvataggio consentito
- Nessuna transazione denominata
- Nessuna transazione contrassegnata
- Nessun supporto per DDL, ad esempio CREATE TABLE, all'interno di una transazione definita dall'utente
Passaggi successivi
Per altre informazioni sull'ottimizzazione delle transazioni, vedere Procedure consigliate per le transazioni. Sono disponibili anche guide consigliate aggiuntive per il pool SQL dedicato e il pool SQL serverless.