C'è una differenza di prestazioni nel commit e nel rollback di una transazione di sola lettura?


8

Apro una transazione (ripetibile) ( BEGIN TRAN) per eseguire alcuni lavori su determinati record. La prima cosa che faccio è verificare se i dati che devo modificare sono nel database. In alcuni casi ci saranno e poi procederò alle mie modifiche. Ma in alcuni casi non ci sarà nulla da fare. In questo caso, o COMMIT TRANo ROLLBACK TRANe ritorno dalla procedura memorizzata. Al momento non sono state ancora apportate modifiche ai dati, quindi l'effetto di commit e rollback è lo stesso.

C'è qualche considerazione che dovrei essere consapevole di scegliere tra commit e rollback? C'è un costo di prestazione diverso? Altre considerazioni?

Risposte:


10

Avendo eseguito questo attraverso una sessione di debug (per aggiornare la mia memoria in errore):

  • Il rollback esegue più controlli rispetto a un commit, ma non dovrebbe comportare un lavoro aggiuntivo o influire notevolmente sulle prestazioni nella situazione descritta.
  • La transazione di lettura / scrittura non inizia veramente a meno che e fino a quando non viene effettuata una modifica dei dati.

Puoi vedere gran parte di questo usando i DMV, ad esempio:

-- Temporary procedure to show the state of the transaction
CREATE PROCEDURE #TranState
    @Comment varchar(100)
AS
BEGIN
    SELECT 
        @Comment AS Comment,
        DTCT.transaction_id,
        database_name =
            CASE DTDT.database_id
                WHEN 32767 THEN N'resource'
                ELSE DB_NAME(DTDT.database_id)
            END,
        tran_begin_time = DTDT.database_transaction_begin_time,
        tran_type =
            CASE DTDT.database_transaction_type
                WHEN 1 THEN 'read/write'
                WHEN 2 THEN 'read only'
                WHEN 3 THEN 'system'
            END,
        tran_state =
            CASE DTDT.database_transaction_state
                WHEN 1 THEN 'The transaction has not been initialized.'
                WHEN 3 THEN 'The transaction has been initialized but has not generated any log records.'
                WHEN 4 THEN 'The transaction has generated log records.'
                WHEN 5 THEN ' The transaction has been prepared.'
                WHEN 10 THEN 'The transaction has been committed.'
                WHEN 11 THEN 'The transaction has been rolled back.'
                WHEN 12 THEN 'The transaction is being committed. In this state the log record is being generated, but it has not been materialized or persisted.'
            END
    FROM sys.dm_tran_current_transaction AS DTCT
    JOIN sys.dm_tran_database_transactions AS DTDT
        ON DTDT.transaction_id = DTCT.transaction_id;
END;

Test su AdventureWorks:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

BEGIN TRANSACTION;

EXECUTE dbo.#TranState @Comment = 'After Begin Tran';

SELECT TOP (1)
    P.Name
FROM Production.Product AS P
ORDER BY 
    P.Name;

EXECUTE dbo.#TranState @Comment = 'After Select';

UPDATE Production.Product
SET Name = N'New Blade'
WHERE Name = N'Blade';

EXECUTE dbo.#TranState @Comment = 'After Update';

-- Or Commit
ROLLBACK TRANSACTION;

EXECUTE dbo.#TranState @Comment = 'After Tran';

Produzione:

Dopo Inizia Tran

Dopo selezionare

Dopo l'aggiornamento

Dopo la transazione

Da un punto di vista puramente pratico (come notato da Aaron in un commento), è probabilmente più sicuro effettuare un rollback per garantire che non vengano apportate modifiche, nel caso in cui il codice venga modificato in futuro. Quindi, si tratta solo di intenti: nessuna modifica = rollback.

Di passaggio, REPEATABLE READè un insolito livello di isolamento da scegliere; non sempre funziona come le persone si aspetterebbero intuitivamente . A seconda delle esigenze, è possibile trovare l' SNAPSHOTisolamento più adatto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.