Transactions with Memory-Optimized TablesTransactions with Memory-Optimized Tables

QUESTO ARGOMENTO SI APPLICA A: sìSQL Server (a partire dalla versione 2016)sìDatabase SQL di AzurenoAzure SQL Data Warehouse noParallel Data Warehouse THIS TOPIC APPLIES TO: yesSQL Server (starting with 2016)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

Questo articolo descrive tutti gli aspetti delle transazioni specifici per le tabelle con ottimizzazione per la memoria e le stored procedure compilate in modo nativo.This article describes all the aspects of transactions that are specific to memory-optimized tables and natively compiled stored procedures.

I livelli di isolamento delle transazioni in SQL Server si applicano in modo diverso alle tabelle con ottimizzazione per la memoria e alle tabelle basate su disco rigido e i meccanismi sottostanti sono diversi.The transaction isolation levels in SQL Server apply differently to memory-optimized tables versus disk-based tables, and the underlying mechanisms are different. Capire le differenze consente al programmatore di progettare un sistema con velocità effettiva elevata.An understanding of the differences helps the programmer design a high throughput system. L'obiettivo di integrità delle transazioni è condiviso in tutti i casi.The goal of transaction integrity is shared in all cases.

Per le condizioni di errore specifiche per le transazioni nelle tabelle con ottimizzazione per la memoria, passare alla sezione Rilevamento dei conflitti e logica di ripetizione dei tentativi.For error conditions specific to transactions on memory-optimized tables, jump to the section Conflict Detection and Retry Logic.

Per informazioni generali, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).For general information, see SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Approccio pessimistico e approccio ottimisticoPessimistic versus Optimistic

Le differenze funzionali sono dovute a un diverso approccio, ottimistico o pessimistico, all'integrità delle transazioni.The functional differences are due to pessimistic versus optimistic approaches to transaction integrity. Le tabelle con ottimizzazione per la memoria usano l'approccio ottimistico:Memory-optimized tables use the optimistic approach:

  • L'approccio pessimistico usa i blocchi per fermare i potenziali conflitti prima che si verifichino.Pessimistic approach uses locks to block potential conflicts before they occur. I blocchi vengono acquisiti quando l'istruzione viene eseguita e vengono rilasciati quando viene eseguito il commit della transazione.Lock are taken when the statement is executed, and released when the transaction is committed.

  • L'approccio ottimistico rileva i conflitti nel momento in cui si verificano ed esegue i controlli di convalida in fase di commit.Optimistic approach detects conflicts as they occur, and performs validation checks at commit time.

    • L'errore 1205, un deadlock, non può verificarsi per una tabella con ottimizzazione per la memoria.Error 1205, a deadlock, cannot occur for a memory-optimized table.

L'approccio ottimistico implica un sovraccarico minore ed è in genere più efficiente, in parte perché i conflitti di transazioni non sono comuni nella maggior parte delle applicazioni.The optimistic approach is less overhead and is usually more efficient, partly because transaction conflicts are uncommon in most applications. La principale differenza funzionale tra l'approccio ottimistico e quello pessimistico è il fatto che, in caso di conflitto, con l'approccio pessimistico si attende, mentre con l'approccio ottimistico una delle transazioni ha esito negativo e deve essere riprovata dal client.The main functional difference between the pessimistic and optimistic approaches is that if a conflict occurs, in the pessimistic approach you wait, while in the optimistic approach one of the transactions fails and needs to be retried by the client. Le differenze funzionali sono maggiori quando è attivato il livello di isolamento REPEATABLE READ e raggiungono il massimo grado per il livello SERIALIZABLE.The functional differences are bigger when the REPEATABLE READ isolation level is in force, and are biggest for the SERIALIZABLE level.

Modalità di avvio della transazioneTransaction Initiation Modes

SQL può avviare le transazioni con le modalità seguenti:SQL Server has the following modes for transaction initiation:

  • Commit automatico : l'inizio di una semplice query o istruzione DML apre in modo implicito una transazione e la fine di questa istruzione esegue implicitamente il commit della transazione stessa.Autocommit - The start of a simple query or DML statement implicitly opens a transaction, and the end of the statement implicitly commits the transaction. Commit automatico è l'impostazione predefinita.Autocommit is the default.

    • In modalità autocommit non è di solito necessario codificare un hint di tabella sul livello di isolamento delle transazioni nella tabella con ottimizzazione per la memoria nella clausola FROM.In autocommit mode, usually you are not required to code a table hint about the transaction isolation level on the memory-optimized table in the FROM clause.
  • Esplicita : Transact-SQL contiene il codice BEGIN TRANSACTION, insieme a un eventuale COMMIT TRANSACTION.Explicit - Your Transact-SQL contains the code BEGIN TRANSACTION, along with an eventual COMMIT TRANSACTION. Due o più istruzioni possono essere riunite nella stessa transazione.Two or more statements can be corralled into the same transaction.

    • In modalità esplicita è necessario usare l'opzione di database MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT o codificare un hint di tabella sul livello di isolamento della transazione nella tabella con ottimizzazione per la memoria nella clausola FROM.In explicit mode, you must either use the database option MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT or code a table hint about the transaction isolation level on the memory-optimized table in the FROM clause.
  • Implicita : quando è attiva SET IMPLICIT_TRANSACTION ON.Implicit - When SET IMPLICIT_TRANSACTION ON is in force. Probabilmente IMPLICIT_BEGIN_TRANSACTION sarebbe un nome migliore, poiché questa opzione non fa altro che eseguire in modo implicito l'equivalente di un'istruzione BEGIN TRANSACTION esplicita prima di ogni istruzione UPDATE se 0 = @@trancount. Perhaps a better name would have been IMPLICIT_BEGIN_TRANSACTION, because all this option does is implicitly perform the equivalent of an explicit BEGIN TRANSACTION before each UPDATE statement if 0 = @@trancount.</span></span> Quindi dipende dal codice T-SQL se viene inviata un'istruzione COMMIT TRANSACTION esplicita.Therefore it is up to your T-SQL code to eventually issue an explicit COMMIT TRANSACTION.

  • Blocco ATOMIC: tutte le istruzioni nei blocchi ATOMIC vengono sempre eseguite come parte di una singola transazione.ATOMIC BLOCK - All statements in ATOMIC blocks always run as part of a single transaction. In caso di esito positivo viene eseguito il commit delle azioni del blocco ATOMIC nel loro complesso oppure, in caso di errore, viene eseguito il rollback di tutte.Either the actions of the atomic block as a whole are committed on success, or the actions are all rolled back when a failure occurs. Ogni stored procedure compilata in modo nativo richiede un blocco ATOMIC.Each natively compiled stored procedure requires an ATOMIC block.

Esempio di codice con modalità esplicitaCode Example with Explicit Mode

Il seguente script Transact-SQL interpretato usa:The following interpreted Transact-SQL script uses:

  • Una transazione esplicita.An explicit transaction.
  • Una tabella con ottimizzazione per la memoria, denominata dbo. Order_mo.A memory-optimized table, named dbo.Order_mo.
  • Il contesto del livello di isolamento delle transazioni READ COMMITTED.The READ COMMITTED transaction isolation level context.

È quindi necessario avere un hint di tabella per la tabella con ottimizzazione per la memoria.Therefore it is necessary to have a table hint on the memory-optimized table. L'hint deve essere per SNAPSHOT o per un livello di isolamento ancora maggiore.The hint must be for SNAPSHOT or an even more isolating level. Nel caso dell'esempio di codice l'hint è WITH (SNAPSHOT).In the case of the code example, the hint is WITH (SNAPSHOT). Se si rimuove questo hint, lo script genera un errore 41368, per il quale un nuovo tentativo automatico non sarebbe appropriato:If this hint is removed, the script would suffer an error 41368, for which an automated retry would be inappropriate:

Errore 41368Error 41368

L'accesso alle tabelle con ottimizzazione per la memoria utilizzando il livello di isolamento READ COMMITTED è supportato solo per transazioni in modalità autocommit.Accessing memory optimized tables using the READ COMMITTED isolation level is supported only for autocommit transactions. Non è invece supportato con le transazioni implicite o esplicite.It is not supported for explicit or implicit transactions. Specificare un livello di isolamento supportato per la tabella con ottimizzazione per la memoria usando un hint di tabella, ad esempio WITH (SNAPSHOT).Provide a supported isolation level for the memory-optimized table using a table hint, such as WITH (SNAPSHOT).

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;  
GO  

BEGIN TRANSACTION;  -- Explicit transaction.  

-- Order_mo  is a memory-optimized table.  
SELECT * FROM  
           dbo.Order_mo  as o  WITH (SNAPSHOT)  -- Table hint.  
      JOIN dbo.Customer  as c  on c.CustomerId = o.CustomerId;  

COMMIT TRANSACTION;

L'hint WITH (SNAPSHOT) non è necessario se si usa l'opzione di database MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT.The need for the WITH (SNAPSHOT) hint can be avoided through the use of the database option MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT. Quando questa opzione è impostata su ON, l'accesso a una tabella con ottimizzazione per la memoria a un livello di isolamento inferiore viene elevato automaticamente al livello di isolamento SNAPSHOT.When this option is set to ON, access to a memory-optimized table under a lower isolation level is automatically elevated to SNAPSHOT isolation.

ALTER DATABASE CURRENT
    SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON;

Controllo delle versioni delle righeRow Versioning

Le tabelle con ottimizzazione per la memoria usano un sistema sofisticato per il controllo delle versioni di riga, che assicura l'efficacia dell'approccio ottimistico, anche al livello di isolamento più rigoroso, SERIALIZABLE.Memory-optimized tables use a highly sophisticated row versioning system that makes the optimistic approach efficient, even at the most strict isolation level of SERIALIZABLE. Per i dettagli, vedere Introduzione alle tabelle con ottimizzazione per la memoria.For details see Introduction to Memory-Optimized Tables.

Le tabelle basate su disco hanno indirettamente un sistema per il controllo delle versioni delle righe quando è impostata l'opzione READ_COMMITTED_SNAPSHOT o è attivo il livello di isolamento SNAPSHOT.Disk-based tables indirectly have a row versioning system when READ_COMMITTED_SNAPSHOT or the SNAPSHOT isolation level is in effect. Questo sistema è basato su tempdb, mentre le strutture di dati ottimizzate per la memoria hanno un controllo delle versioni delle righe incorporato, per garantire la massima efficienza.This system is based on tempdb, while memory-optimized data structures have row versioning built in, for maximum efficiency.

Livelli di isolamentoIsolation Levels

La tabella che segue indica i livelli di isolamento possibili per le transazioni, ordinate dall'isolamento minimo a quello massimo.The following table lists the possible levels of transaction isolation, in sequence from least isolation to most. Per informazioni dettagliate sui conflitti che possono verificarsi e sulla logica di ripetizione dei tentativi per affrontare questi conflitti, vedere Rilevamento dei conflitti e logica di ripetizione dei tentativi.For details about conflicts that can occur and retry logic to deal with these conflicts, see Conflict Detection and Retry Logic.

Livello di isolamentoIsolation Level DescrizioneDescription
READ UNCOMMITTEDREAD UNCOMMITTED Non disponibile: non è possibile accedere alle tabelle con ottimizzazione per la memoria con isolamento Read Uncommitted.Not available: memory-optimized tables cannot be accessed under Read Uncommitted isolation. È comunque possibile accedere alle tabelle con ottimizzazione per la memoria con isolamento SNAPSHOT se l'opzione TRANSACTION ISOLATION LEVEL a livello di sessione è impostata su READ UNCOMMITTED, usando l'hint di tabella WITH (SNAPSHOT) o impostando l'opzione di database MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT su ON.It is still possible to access memory-optimized tables under SNAPSHOT isolation if the session-level TRANSACTION ISOLATION LEVEL is set to READ UNCOMMITTED, by using the WITH (SNAPSHOT) table hint or setting the database setting MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT to ON.
READ COMMITTEDREAD COMMITTED L'opzione è supportata per le tabelle con ottimizzazione per la memoria solo quando è attiva la modalità autocommit.Supported for memory-optimized tables only when the autocommit mode is in effect. È comunque possibile accedere alle tabelle con ottimizzazione per la memoria con isolamento SNAPSHOT se l'opzione TRANSACTION ISOLATION LEVEL a livello di sessione è impostata su READ COMMITTED, usando l'hint di tabella WITH (SNAPSHOT) o impostando l'opzione di database MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT su ON.It is still possible to access memory-optimized tables under SNAPSHOT isolation if the session-level TRANSACTION ISOLATION LEVEL is set to READ COMMITTED, by using the WITH (SNAPSHOT) table hint or setting the database setting MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT to ON.

Se l'opzione di database READ_COMMITTED_SNAPSHOT è impostata su ON, non è possibile accedere a una tabella ottimizzata per la memoria e a una tabella basata su disco con il livello di isolamento READ COMMITTED nella stessa istruzione.If the database option READ_COMMITTED_SNAPSHOT is set to ON, it is not allowed to access both a memory-optimized and a disk-based table under READ COMMITTED isolation in the same statement.
SNAPSHOTSNAPSHOT Supportata per le tabelle con ottimizzazione per la memoria.Supported for memory-optimized tables.

Internamente, SNAPSHOT è il livello di isolamento della transazione meno rigoroso per le tabelle con ottimizzazione per la memoria.Internally SNAPSHOT is the least demanding transaction isolation level for memory-optimized tables.

SNAPSHOT usa meno risorse di sistema rispetto a REPEATABLE READ o SERIALIZABLE.SNAPSHOT uses fewer system resources than does REPEATABLE READ or SERIALIZABLE.
REPEATABLE READREPEATABLE READ Supportata per le tabelle con ottimizzazione per la memoria.Supported for memory-optimized tables. Il livello di isolamento REPEATABLE READ garantisce che, in fase di commit, nessuna transazione simultanea abbia aggiornato nessuna delle righe lette da questa transazione.The guarantee provided by REPEATABLE READ isolation is that, at commit time, no concurrent transaction has updated any of the rows read by this transaction.

Dato il modello ottimistico, alle transazioni simultanee non è impedito di aggiornare le righe lette dalla transazione.Because of the optimistic model, concurrent transactions are not prevented from updating rows read by this transaction. In fase di commit, però, questa transazione verifica che l'isolamento REPEATABLE READ non sia stato violato.Instead, at commit time this transaction validated that REPEATABLE READ isolation has not been violated. Se ciò è accaduto, viene eseguito il rollback della transazione e questa deve essere riprovata.If it has, this transaction is rolled back and must be retried.
SERIALIZABLESERIALIZABLE Supportata per le tabelle con ottimizzazione per la memoria.Supported for memory-optimized tables.

Il nome Serializable è dovuto al fatto che l'isolamento è così rigido che è quasi come se le transazioni fossero eseguite in serie anziché contemporaneamente.Named Serializable because the isolation is so strict that it is almost a bit like having the transactions run in series rather than concurrently.

Fasi e durata delle transazioniTransaction Phases and Lifetime

Quando è interessata una tabella ottimizzata per la memoria, la durata di una transazione attraversa le fasi illustrate nell'immagine seguente:When a memory-optimized table is involved, the lifetime of a transaction progresses through the phases as displayed in the following image:

hekaton_transactions

Seguono le descrizioni delle fasi.Descriptions of the phases follow.

Elaborazione normale: Fase 1 di 3Regular Processing: Phase 1 (of 3)

  • Questa fase comprende l'esecuzione di tutte le query e delle istruzioni DML nella query.This phase is composed of the execution of all queries and DML statements in the query.
  • Durante questa fase, le istruzioni vedono la versione delle tabelle con ottimizzazione per la memoria valida al momento dell'avvio logico della transazione.During this phase, the statements see the version of the memory-optimized tables as of the logical start time of the transaction.

Convalida: Fase 2 di 3Validation: Phase 2 (of 3)

  • La fase di convalida inizia con l'assegnazione dell'ora di fine, contrassegnando la transazione come completata a livello logico.The validation phase begins by assigning the end time, thereby marking the transaction as logically complete. Questo completamento rende visibili tutte le modifiche della transazione per le altre transazioni dipendenti da questa transazione.This completion makes all changes of the transaction visible to other transactions which take a dependency on this transaction. Il commit delle transazioni dipendenti non è consentito fino al commit di questa transazione.The dependent transactions are not allowed to commit until this transaction has successfully committed. Inoltre, le transazioni che contengono queste dipendenze non possono restituire set di risultati al client per assicurare che il client veda solo i dati di cui è stato eseguito il commit nel database.In addition, transactions which hold such dependencies are not allowed to return result sets to the client, to ensure the client only sees data that has been successfully committed to the database.
  • Questa fase comprende la lettura ripetibile e la convalida serializzabile.This phase comprises the repeatable read and serializable validation. Per la convalida di lettura ripetibile, verifica se le righe lette dalla transazione sono state aggiornate da quel momento.For repeatable read validation, it checks whether any of the rows read by the transaction has since been updated. Per la convalida serializzabile, verifica se sono state inserite righe in qualsiasi intervallo di dati analizzato da questa transazione.For serializable validation it checks whether any row has been inserted into any data range scanned by this transaction. Come indicato nella tabella Livelli di isolamento e conflitti, la convalida di lettura ripetibile e la convalida serializzabile possono avere luogo quando si usa l'isolamento snapshot, per convalidare la coerenza dei vincoli di chiave univoca ed esterna.Per the table in Isolation Levels and Conflicts, both repeatable read and serializable validation can happen when using snapshot isolation, to validate consistency of unique and foreign key constraints.

Elaborazione del commit: Fase 3 di 3Commit Processing: Phase 3 (of 3)

  • Durante la fase di commit, le modifiche apportate alle tabelle durevoli vengono scritte nel log, che a sua volta viene scritto su disco.During the commit phase, the changes to durable tables are written to the log, and the log is written to disk. Il controllo viene quindi restituito al client.Then control is returned to the client.
  • Al termine dell'elaborazione del commit, a tutte le transazioni dipendenti viene indicato che possono eseguire il commit.After commit processing completes, all dependent transactions are notified that they can commit.

Come sempre, è consigliabile ridurre l'entità e la durata delle unità di lavoro transazionali ai valori minimi consentiti dalle proprie esigenze in termini di dati.As always, you should try to keep your transactional units of work as minimal and brief as is valid for your data needs.

Rilevamento dei conflitti e logica di ripetizione dei tentativiConflict Detection and Retry Logic

Esistono due tipi di condizioni di errore relative alle transazioni che causano l'esito negativo e il rollback della transazione.There are two kinds of transaction-related error conditions that cause a transaction to fail and roll back. Nella maggior parte dei casi, quando si verifica un errore di questo tipo è necessario ritentare la transazione, analogamente a quanto accade in caso di deadlock.In most cases, once such a failure occurs, the transaction needs to be retried, similar to when a deadlock occurs.

  • Conflitti tra le transazioni simultanee.Conflicts between concurrent transactions. Si tratta di conflitti di aggiornamento ed errori di convalida, che possono essere dovuti a violazioni a livello di isolamento della transazione o violazioni di vincoli.These are update conflicts and validation failures, and can be due to transaction isolation level violations or constraint violations.
  • Errori di dipendenza.Dependency failures. Derivano dal mancato commit della transazione da cui si dipende o dall'aumento eccessivo del numero di dipendenze.These result from transactions that you depend on failing to commit, or from the number of dependencies growing too large.

Di seguito sono indicate le condizioni di errore che possono causare errori delle transazioni durante l'accesso alle tabelle ottimizzate per la memoria.The following are the error conditions that can cause transactions to fail when they access memory-optimized tables.

Codice erroreError Code DescrizioneDescription CausaCause
4130241302 Si è tentato di aggiornare una riga che è stata aggiornata in un'altra transazione dopo l'avvio di questa transazione.Attempted to update a row that was updated in a different transaction since the start of the present transaction. Questa condizione di errore si verifica se due transazioni simultanee tentano di aggiornare o eliminare la stessa riga nello stesso momento.This error condition occurs if two concurrent transactions attempt to update or delete the same row at the same time. Una delle due transazioni riceve questo messaggio di errore e dovrà essere ritentata.One of the two transactions receives this error message and will need to be retried.

4130541305 Errore di convalida di lettura ripetibile.Repeatable read validation failure. Una riga letta da una tabella con ottimizzazione per la memoria è stata aggiornata da un'altra transazione che ha eseguito il commit prima del commit di questa transazione.A row read from a memory-optimized table this transaction has been updated by another transaction that has committed before the commit of this transaction. Questo errore può verificarsi quando si usa l'isolamento REPEATABLE READ o SERIALIZABLE e anche se le azioni di una transazione simultanea causano la violazione del vincolo di chiave esterna.This error can occur when using REPEATABLE READ or SERIALIZABLE isolation, and also if the actions of a concurrent transaction cause violation of a FOREIGN KEY constraint.

Questa violazione simultanea dei vincoli di chiave esterna è rara e solitamente indica un problema relativo alla logica dell'applicazione o all'immissione di dati.Such concurrent violation of foreign key constraints is rare, and typically indicates an issue with the application logic or with data entry. Tuttavia, l'errore può verificarsi anche se non esiste alcun indice nelle colonne coinvolte nel vincolo FOREIGN KEY.However, the error can also occur if there is no index on the columns involved with the FOREIGN KEY constraint. Per questo motivo è consigliabile creare sempre un indice nelle colonne di chiavi esterne in una tabella con ottimizzazione per la memoria.Therefore, the guidance is to always create an index on foreign key columns in a memory-optimized table.

Per considerazioni più specifiche sugli errori di convalida dovuti a violazioni di chiavi esterne, vedere questo post di blog del team di consulenza clienti di SQL Server.For more detailed considerations about validation failures caused by foreign key violations, see this blog post by the SQL Server Customer Advisory Team.
4132541325 Errore di convalida serializzabile.Serializable validation failure. È stata inserita una nuova riga in un intervallo analizzato in precedenza da questa transazione.A new row was inserted into a range that was scanned earlier by the present transaction. Si tratta di una cosiddetta riga fantasma.We call this a phantom row. Questo errore può verificarsi quando si usa l'isolamento SERIALIZABLE e anche se le azioni di una transazione simultanea causano la violazione di un vincolo PRIMARY KEY, UNIQUE o FOREIGN KEY.This error can occur when using SERIALIZABLE isolation, and also if the actions of a concurrent transaction cause violation of a PRIMARY KEY, UNIQUE, or FOREIGN KEY constraint.

Questa violazione simultanea dei vincoli è rara e solitamente indica un problema relativo alla logica dell'applicazione o all'immissione di dati.Such concurrent constraint violation is rare, and typically indicates an issue with the application logic or data entry. Comunque, analogamente agli errori di convalida di lettura ripetibile, questo errore può verificarsi anche se è presente un vincolo FOREIGN KEY senza indice sulle colonne coinvolte.However, similar to repeatable read validation failures, this error can also occur if there is a FOREIGN KEY constraint with no index on the columns involved.
4130141301 Errore di dipendenza: è stata acquisita una dipendenza da un'altra transazione di cui in seguito non è stato eseguito il commit.Dependency failure: a dependency was taken on another transaction that later failed to commit. Questa transazione (Tx1) ha acquisito una dipendenza da un'altra transazione (Tx2) mentre tale transazione (Tx2) era in fase di elaborazione della convalida o del commit, leggendo i dati scritti da Tx2.This transaction (Tx1) took a dependency on another transaction (Tx2) while that transaction (Tx2) was in its validation or commit processing phase, by reading data that was written by Tx2. Successivamente, Tx2 non è riuscita a eseguire il commit.Tx2 subsequently failed to commit. Le cause più comuni per il mancato commit di Tx2 sono gli errori di convalida di lettura ripetibile (41305) e serializzabile (41325). Una causa meno comune è un errore di I/O del log.Most common causes for Tx2 to fail to commit are repeatable read (41305) and serializable (41325) validation failures; a less common cause is log IO failure.
4183941839 La transazione ha superato il numero massimo di dipendenze di commit.Transaction exceeded the maximum number of commit dependencies. Il numero di transazioni da cui una determinata transazione (Tx1) può dipendere è limitato.There is a limit on the number of transactions a given transaction (Tx1) can depend on. Queste transazioni sono le dipendenze in uscita.Those transactions are the outgoing dependencies. Anche il numero di transazioni che possono dipendere da una determinata transazione (Tx1) è limitato.In addition, there is a limit on the number of transactions that can depend on a given transaction (Tx1). Queste transazioni sono le dipendenze in ingresso.These transactions are the incoming dependencies. Il limite in entrambi i casi è 8.The limit for both is 8.

Lo scenario più comune per questo errore è la presenza di un ampio numero di transazioni di lettura che accedono a dati scritti da una singola transazione di scrittura.The most common case for this failure is where there is a large number of read transactions accessing data written by a single write transaction. Le probabilità che si verifichi questa condizione aumentano se tutte le transazioni di lettura eseguono ampie analisi degli stessi dati e se l'elaborazione della convalida o del commit della transazione di scrittura richiede molto tempo, ad esempio quando la transazione di scrittura esegue vaste analisi con il livello di isolamento serializable (aumenta la durata della fase di convalida) o il log delle transazioni si trova in un dispositivo di I/O di log lento (aumenta la durata dell'elaborazione del commit).The likelihood of hitting this condition increases if the read transactions are all performing large scans of the same data and if validation or commit processing of the write transaction takes long, for example the write transaction performs large scans under serializable isolation (increases length of the validation phase) or the transaction log is placed on a slow log IO device (increases length of commit processing). Se le transazioni di lettura eseguono ampie analisi ed è previsto che accedano solo a poche righe, potrebbe mancare un indice.If the read transactions are performing large scans and they are expected to access only few rows, an index might be missing. Analogamente, se la transazione di scrittura usa l'isolamento serializable ed esegue ampie analisi, ma è previsto che acceda a poche righe, anche questo indica la mancanza di un indice.Similarly, if the write transaction uses serializable isolation and is performing large scans but is expected to access only few rows, this is also an indication of a missing index.

Il limite sul numero delle dipendenze di commit può essere eliminato usando il flag di traccia 9926.The limit on number of commit dependencies can be lifted by use Trace Flag 9926. È importante usare questo flag di traccia solo se questa condizione di errore si presenta anche dopo avere verificato che non manca alcun indice, perché potrebbe mascherare questi problemi nei casi sopra indicati.Use this trace flag only if you are still hitting this error condition after confirming that there are no missing indexes, as it could mask these issues in the above-mentioned cases. Un'altra precauzione è il fatto che i grafici complessi delle dipendenze, in cui ogni transazione ha un numero elevato di dipendenze in ingresso e in uscita e ogni transazione può avere molti livelli di dipendenze, possono determinare inefficienze nel sistema.Another caution is that complex dependency graphs, where each transaction has a large number of incoming as well as outgoing dependencies, and individual transactions have many layers of dependencies, can lead to inefficiencies in the system.

Logica di ripetizione dei tentativiRetry Logic

Quando una transazione ha esito negativo a causa di una delle condizioni sopra indicate, è necessario ritentare la transazione.When a transaction fails due to any of the above-mentioned conditions, the transaction should be retried.

La logica di ripetizione dei tentativi può essere implementata sul lato client o server.Retry logic can be implemented at the client or server side. In generale, è consigliabile implementare la logica di ripetizione dei tentativi sul lato client perché risulta più efficiente e consente di gestire i set di risultati restituiti dalla transazione prima che si verifichi l'errore.The general recommendation is to implement retry logic on the client side, as it is more efficient, and allows you to deal with result sets returned by the transaction before the failure occurs.

Esempio di codice di ripetizione T-SQLRetry T-SQL Code Example

La logica di ripetizione sul lato server mediante T-SQL deve essere usata solo per le transazioni che non restituiscono set di risultati al client.Server-side retry logic using T-SQL should only be used for transactions that do not return result sets to the client. In caso contrario, tentativi ripetuti possono comportare la restituzione al client di set di risultati aggiuntivi oltre a quelli previsti.Otherwise, retries can potentially result in additional result sets beyond those anticipated being returned to the client.

Lo script T-SQL interpretato riportato di seguito illustra l'aspetto che può avere una logica di ripetizione per gli errori associati ai conflitti tra transazioni relativi alle tabelle con ottimizzazione per la memoria.The following interpreted T-SQL script illustrates what retry logic can look like for the errors associated with transaction conflicts involving memory-optimized tables.

-- Retry logic, in Transact-SQL.
DROP PROCEDURE If Exists usp_update_salesorder_dates;
GO

CREATE PROCEDURE usp_update_salesorder_dates
AS
BEGIN
    DECLARE @retry INT = 10;

    WHILE (@retry > 0)
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;

            UPDATE dbo.SalesOrder_mo WITH (SNAPSHOT)
                set OrderDate = GetUtcDate()
                where CustomerId = 42;

            UPDATE dbo.SalesOrder_mo WITH (SNAPSHOT)
                set OrderDate = GetUtcDate()
                where CustomerId = 43;

            COMMIT TRANSACTION;

            SET @retry = 0;  -- //Stops the loop.
        END TRY

        BEGIN CATCH
            SET @retry -= 1;

            IF (@retry > 0 AND
                ERROR_NUMBER() in (41302, 41305, 41325, 41301, 41839, 1205)
                )
            BEGIN
                IF XACT_STATE() = -1
                    ROLLBACK TRANSACTION;

                WAITFOR DELAY '00:00:00.001';
            END
            ELSE
            BEGIN
                PRINT 'Suffered an error for which Retry is inappropriate.';
                THROW;
            END
        END CATCH

    END -- //While loop
END;
GO

--  EXECUTE usp_update_salesorder_dates;

Transazione tra contenitoriCross-Container Transaction

Una transazione è detta transazione tra contenitori se:A transaction is called a cross-container transaction if it:

  • Accede a una tabella con ottimizzazione per la memoria da un codice Transact-SQL interpretato oAccesses a memory-optimized table from interpreted Transact-SQL; or
  • Esegue una procedura nativa quando una transazione è già aperta (XACT_STATE() = 1).Executes a native proc when a transaction is already open (XACT_STATE() = 1).

Il termine "tra contenitori" deriva dal fatto che la transazione viene eseguita sui contenitori di gestione delle transazioni, uno per le tabelle basate su disco e uno per le tabelle con ottimizzazione per la memoria.The term "cross-container" derives from the fact that the transaction runs across the two transaction management containers, one for disk-based tables and one for memory-optimized tables.

All'interno di una singola transazione tra contenitori, è possibile usare diversi livelli di isolamento per l'accesso alle tabelle con ottimizzazione per la memoria e su disco.Within a single cross-container transaction, different isolation levels can be used for accessing disk-based and memory-optimized tables. Questa differenza viene espressa tramite hint di tabella espliciti come WITH (SERIALIZABLE) o tramite l'opzione di database MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT, che eleva implicitamente a snapshot il livello di isolamento per la tabella con ottimizzazione per la memoria se TRANSACTION ISOLATION LEVEL è configurato come READ COMMITTED o READ UNCOMMITTED.This difference is expressed through explicit table hints such as WITH (SERIALIZABLE) or through the database option MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT, which implicitly elevates the isolation level for memory-optimized table to snapshot if the TRANSACTION ISOLATION LEVEL is configured as READ COMMITTED or READ UNCOMMITTED.

Nell'esempio di codice Transact-SQL che segue:In the following Transact-SQL code example:

  • Alla tabella basata su disco, Table_D1, si accede usando il livello di isolamento READ COMMITTED.The disk-based table, Table_D1, is accessed using the READ COMMITTED isolation level.
  • Alla tabella con ottimizzazione per la memoria Table_MO7 si accede usando il livello di isolamento SERIALIZABLE.The memory-optimized table Table_MO7 is accessed using the SERIALIZABLE isolation level. A Table_MO6 non è associato un livello di isolamento specifico perché gli inserimenti sono sempre coerenti ed eseguiti essenzialmente con il livello di isolamento serializable.Table_MO6 does not have a specific associated isolation level, since inserts are always consistent and executed essentially under serializable isolation.
-- Different isolation levels for
-- disk-based tables versus memory-optimized tables,
-- within one explicit transaction.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
go

BEGIN TRANSACTION;

    -- Table_D1 is a traditional disk-based table, accessed using READ COMMITTED isolation.

    SELECT * FROM Table_D1;


    -- Table_MO6 and Table_MO7 are memory-optimized tables.
    -- Table_MO7 is accessed using SERIALIZABLE isolation,
    --   while Table_MO6 does not have a specific isolation level.

    INSERT Table_MO6
        SELECT * FROM Table_MO7 WITH (SERIALIZABLE);

COMMIT TRANSACTION;
go

LimitazioniLimitations

  • Le transazioni tra database non sono supportate per le tabelle con ottimizzazione per la memoria.Cross-database transactions are not supported for memory-optimized tables. Se una transazione accede a una tabella con ottimizzazione per la memoria, non può accedere a qualsiasi altro database, tranne:If a transaction accesses a memory-optimized table, the transaction cannot access any other database, except for:

    • il database tempdb.tempdb database.
    • Proprietà di sola lettura dal database master.Read-only from the master database.
  • Le transazioni distribuite non sono supportate: quando si usa BEGIN DISTRIBUTED TRANSACTION, la transazione non può accedere a una tabella con ottimizzazione per la memoria.Distributed transactions are not supported: When BEGIN DISTRIBUTED TRANSACTION is used, the transaction cannot access a memory-optimized table.

Stored procedure compilate in modo nativoNatively Compiled Stored Procedures

  • In una procedura nativa ATOMIC BLOCK deve dichiarare il livello di isolamento della transazione per l'intero blocco, ad esempio:In a native proc, the ATOMIC block must declare the transaction isolation level for the whole block, such as:

    • ... BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, ...) ...
  • Non sono consentite istruzioni di controllo delle transazioni esplicite nel corpo di una procedura nativa.No explicit transaction control statements are allowed within the body of a native proc. Le opzioni BEGIN TRANSACTION, ROLLBACK TRANSACTION e così via sono tutte non consentite.BEGIN TRANSACTION, ROLLBACK TRANSACTION, and so on, are all disallowed.

  • Per altre informazioni sul controllo delle transazioni con i blocchi ATOMIC, vedere Blocchi ATOMIC.For more information about transaction control with ATOMIC blocks, see Atomic Blocks