Ho riscontrato un problema simile a The current transaction cannot be committed and cannot support operations that write to the log file, ma ho una domanda di follow-up.Errore di transazione SQL: impossibile eseguire il commit della transazione corrente e non supportare le operazioni che scrivono nel file di registro
La risposta non fa riferimento Using TRY...CATCH in Transact-SQL, che tornerò a in un secondo ...
Il mio codice (ereditata, naturalmente) ha la forma semplificata:
SET NOCOUNT ON
SET XACT_ABORT ON
CREATE TABLE #tmp
SET @transaction = 'insert_backtest_results'
BEGIN TRANSACTION @transaction
BEGIN TRY
--do some bulk insert stuff into #tmp
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION @transaction
SET @errorMessage = 'bulk insert error importing results for backtest '
+ CAST(@backtest_id as VARCHAR) +
'; check backtestfiles$ directory for error files ' +
' error_number: ' + CAST(ERROR_NUMBER() AS VARCHAR) +
' error_message: ' + CAST(ERROR_MESSAGE() AS VARCHAR(200)) +
' error_severity: ' + CAST(ERROR_SEVERITY() AS VARCHAR) +
' error_state ' + CAST(ERROR_STATE() AS VARCHAR) +
' error_line: ' + CAST(ERROR_LINE() AS VARCHAR)
RAISERROR(@errorMessage, 16, 1)
RETURN -666
END CATCH
BEGIN TRY
EXEC usp_other_stuff_1 @whatever
EXEC usp_other_stuff_2 @whatever
-- a LOT of "normal" logic here... inserts, updates, etc...
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION @transaction
SET @errorMessage = 'error importing results for backtest '
+ CAST(@backtest_id as VARCHAR) +
' error_number: ' + CAST(ERROR_NUMBER() AS VARCHAR) +
' error_message: ' + CAST(ERROR_MESSAGE() AS VARCHAR(200)) +
' error_severity: ' + CAST(ERROR_SEVERITY() AS VARCHAR) +
' error_state ' + CAST(ERROR_STATE() AS VARCHAR) +
' error_line: ' + CAST(ERROR_LINE() AS VARCHAR)
RAISERROR(@errorMessage, 16, 1)
RETURN -777
END CATCH
RETURN 0
penso io avere abbastanza informazioni per giocarci e capirlo da solo ... sfortunatamente riprodurre l'errore si sta dimostrando dannatamente vicino impossibile. Quindi spero che chiedere qui aiuterà a chiarire la mia comprensione del problema e della soluzione.
Questa stored procedure è, ad intermittenza, gettando errori come questo:
error importing results for backtest 9649 error_number: 3930 error_message: The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction. error_severity: 16 error_state 1 error_line: 217
Così, ovviamente, l'errore sta venendo dal 2 ° blocco catch
In base a quello che ho letto in Using TRY...CATCH in Transact-SQL, I pensate che quello che sta succedendo è che quando viene lanciata l'eccezione, l'uso di XACT_ABORT
sta causando la "chiusura e il rollback" della transazione ... e quindi la prima riga di BEGIN CATCH
tenta ciecamente di tornare indietro.
Non so il motivo per cui lo sviluppatore originale abilitato XACT_ABORT
, così sto pensando la soluzione migliore (che rimuoverlo) sarebbe quella di utilizzare XACT_STATE()
a rotolare indietro solo se v'è una transazione (<>0
). Suona ragionevole? Mi sto perdendo qualcosa?
Inoltre, la menzione di registrazione nel messaggio di errore mi fa pensare: c'è un altro problema, potenzialmente con la configurazione? Il nostro uso di RAISEERROR()
in questo scenario contribuisce al problema? Viene registrato, in alcuni casi in cui la registrazione non è possibile, come allude il messaggio di errore?
Il modello assume transazioni all'interno del blocco try; abbiamo più blocchi try all'interno di 1 transazione. –
@Adam: riguarda il modo in cui gestisci "XACT_STATE" e le transazioni nel blocco CATCH. È possibile avere più blocchi try in una transazione utilizzando questo stesso modello. L'idea è di capire come interagiscono le transazioni e i blocchi catch e come bonus si ottiene anche la gestione delle transazioni nidificate e dei punti di salvataggio, che è molto utile nell'elaborazione batch, poiché dà la possibilità di riprendere il resto del batch anche se uno l'entrata era fallita. –
Ho proseguito e ho completato il rollback in un 'if XACT_STATE() <> 0', ma solo il tempo ci dirà se questo lo risolve per noi. Suppongo che andrò avanti e accetto la tua risposta per ora. –