Mam podobny problem do The current transaction cannot be committed and cannot support operations that write to the log file, ale mam kolejne pytanie.Błąd transakcji SQL: Bieżąca transakcja nie może zostać zatwierdzona i nie obsługuje operacji zapisujących do pliku dziennika.
Odpowiedź nie odwołuje Using TRY...CATCH in Transact-SQL, który Wrócę w sekundę ...
Mój kod (dziedziczone, oczywiście) ma uproszczoną postać:
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
myślę Mam wystarczającą ilość informacji, aby po prostu się z tym bawić i sam to rozgryźć ... niestety odtworzenie błędu okazuje się prawie niemożliwe. Mam więc nadzieję, że zapytanie tutaj pomoże wyjaśnić moją wiedzę na temat problemu i rozwiązania.
Ta procedura przechowywana jest przerywany, rzucanie błędy jak ten:
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
Tak oczywiście błąd jest pochodzących od 2 bloku catch
Na podstawie tego co czytałem w Using TRY...CATCH in Transact-SQL, ja pomyśl, co się dzieje, gdy wyjątek zostanie rzucony, użycie XACT_ABORT
powoduje, że transakcja zostaje "zakończona i wycofana" ... a następnie pierwsza linia BEGIN CATCH
ślepo próbuje wycofać.
nie wiem dlaczego oryginalny deweloper włączona XACT_ABORT
, więc myślę, że lepszym rozwiązaniem (niż usunięcie go) byłoby użyć XACT_STATE()
tylko cofnąć jeśli nie jest transakcją (<>0
). Czy to brzmi rozsądnie? Czy czegoś brakuje?
Dodaje się również wzmianka o logowaniu się do komunikatu o błędzie: Czy istnieje inny problem, potencjalnie związany z konfiguracją? Czy korzystanie z tego RAISEERROR()
w tym scenariuszu przyczynia się do problemu? Czy to się loguje, w jakimś przypadku, gdy logowanie nie jest możliwe, o czym wspomina komunikat o błędzie?
Twój szablon przyjmuje transakcje wewnątrz bloku try; mamy wiele bloków try wewnątrz 1 transakcji. –
@Adam: chodzi o sposób obsługi "XACT_STATE" i transakcji w bloku CATCH. Możesz mieć wiele bloków try w jednej transakcji przy użyciu tego samego szablonu. Chodzi o to, aby zrozumieć, w jaki sposób transakcje i bloki catch wchodzą ze sobą w interakcje, a jako bonus można uzyskać obsługę transakcji zagnieżdżonych i punktów zapisywania, co jest bardzo przydatne w przetwarzaniu wsadowym, ponieważ daje możliwość wznowienia reszty partii, nawet jeśli wpis nie powiódł się. –
Poszedłem do przodu i zawijałem instrukcję rollback w 'if XACT_STATE() <> 0', ale tylko czas pokaże, czy to rozwiązało dla nas. Chyba pójdę do przodu i zaakceptuję na razie twoją odpowiedź. –