SQL 트랜잭션 오류:현재 트랜잭션을 커밋할 수 없으며 로그 파일에 쓰는 작업을 지원할 수 없습니다.
현재 트랜잭션을 커밋할 수 없으며 로그 파일에 기록하는 작업을 지원할 수 없습니다.와 비슷한 문제가 있습니다. 하지만 후속 질문이 있습니다.
여기에 대한 답은 TRY를 사용하는...Transact-SQL에서 캐치(CATCH), 잠시 후에 다시...
내 코드(물론 상속됨)는 단순화된 형태를 갖습니다.
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
내가 가지고 있는 정보는 충분히 있다고 생각해 그냥 가지고 놀면서 스스로 알아낼 수 있는...불행히도 오류를 재현하는 것은 거의 불가능한 것으로 드러나고 있습니다.그래서 여기에 문의하는 것이 문제와 해결책에 대한 이해를 명확히 하는 데 도움이 되기를 바랍니다.
이 저장 프로시저는 간헐적으로 다음과 같은 오류를 던지는 것입니다.
backtest 9649 error_number: 3930 error_graphics에 대한 결과 가져오기 오류:현재 트랜잭션을 커밋할 수 없으며 로그 파일에 쓰는 작업을 지원할 수 없습니다.트랜잭션을 롤백합니다.error_state 1 error_line : 217
그럼 분명히 두번째 캐치블럭에서 오류가 발생하고 있습니다.
제가 'TRY 사용하기'에서 읽은 내용을 바탕으로...Transact-SQL의 캐치, 내 생각엔 예외가 던져지면 의 사용으로 인해 트랜잭션이 "종료되고 롤백되는" 현상이 발생한다고 생각합니다. 그리고 그 다음에 첫번째 줄.BEGIN CATCH
맹목적으로 다시 되돌리려고 하는 겁니다
원래 개발자가 왜 활성화했는지 모르겠습니다.XACT_ABORT
(보다) 더해결책은 사용하는 합니다, (하는 보다 은 은 하는 보다 XACT_STATE()
에만)<>0
그게 합리적이라고 생각하십니까?내가 뭘 빼놓았나요?
또한 오류 메시지에 로그인했다는 언급은 다음과 같은 의문을 갖게 합니다.구성에 문제가 있을 가능성이 있습니까?우리가 사용하는 것은RAISEERROR()
이 시나리오에서 문제에 기여하고 있습니까?오류 메시지가 암시하는 것처럼 기록이 불가능한 경우에 기록이 됩니까?
당신은 항상 확인할 필요가 있습니다.XACT_STATE()
, XACT_ABORT
세팅예외 처리 및 중첩 트랜잭션에서 TRY/CATCH 컨텍스트의 트랜잭션을 처리해야 하는 저장 프로시저용 템플릿의 예는 다음과 같습니다.
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(),
@message = ERROR_MESSAGE(),
@xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
위의 논의에서 몇 가지 오해가 있습니다.
먼저 트랜잭션을 항상 롤백할 수 있습니다.거래 상황이 어떻든 간에따라서 XACT_STATE는 롤백 전이 아니라 COMIT 전에만 확인하면 됩니다.
코드의 오류에 관해서는 TRY 안에 트랜잭션을 넣길 원할 것입니다.그러면 캐치에서 가장 먼저 해야 할 일은 다음과 같습니다.
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION @transaction
그런 다음 위의 설명이 끝나면 이메일이나 필요한 것을 보낼 수 있습니다. (참고: 롤백하기 전에 이메일을 보낸다면 "할 수 없는..." 메시지를 확실히 받을 수 있습니다.write to log file" 오류가 발생했습니다.
이 문제는 작년에 발생한 문제이므로 지금쯤 해결하셨으면 좋겠습니다 :-) 레무스가 올바른 방향으로 당신을 가리켰습니다.
경험칙상...TRY는 오류가 발생하면 즉시 CATCH로 점프합니다.그런 다음 CATCH에 있을 때 XACT_STATE를 사용하여 커밋 가능 여부를 결정할 수 있습니다.그러나 항상 캐치에서 롤백(rollback)을 원하는 경우에는 상태를 전혀 확인할 필요가 없습니다.
트리거가 활성화된 테이블에서 레코드를 업데이트하는 동안 이 오류가 발생했습니다.예를 들어, 테이블 'Table1'에 트리거 'Trigger1'이 있습니다.업데이트 쿼리를 사용하여 'Table1'을 업데이트하려고 하면 동일한 오류가 발생합니다.쿼리의 레코드를 둘 이상 업데이트하는 경우 동일한 테이블에서 활성화된 경우 여러 항목의 업데이트를 지원하지 않으므로 'Trigger1'에서 이 오류가 발생하기 때문입니다.업데이트 전에 트리거 비활성화를 시도한 후 업데이트 작업을 진행했고 오류 없이 완료되었습니다.
DISABLE TRIGGER Trigger1 ON Table1;
Update query --------
Enable TRIGGER Trigger1 ON Table1;
위와 비슷한 문제가 발생하여 같은 오류 메시지를 받고 있었습니다.위의 답변들은 도움이 되었지만, 제가 필요로 했던 것은 아니었고, 사실은 조금 더 간단했습니다.
다음과 같이 구성된 저장 프로시저가 있었습니다.
SET XACT_ABORT ON
BEGIN TRY
--Stored procedure logic
BEGIN TRANSACTION
--Transaction logic
COMMIT TRANSACTION
--More stored procedure logic
END TRY
BEGIN CATCH
--Handle errors gracefully
END CATCH
TRY...CATCH
저장 프로시저 로직의 오류를 처리하는 데 사용되었습니다.한되어 있으며, 이한어이며면당는당에해다지이가서e다ttdtpy당dde는eafnt,의esdfdn한이gr에만CATCH
블록이지만 SQL Transaction Error 메시지와 함께 오류가 발생합니다.
이것은 다른 것을 추가함으로써 해결되었습니다.TRY...CATCH
그럴만한 포장지ROLLBACK
거래와THROW
실수.이는 이 단계에서 발생한 모든 오류를 메인에서 우아하게 처리할 수 있음을 의미합니다.CATCH
나머지 저장 프로시저에 따라 차단합니다.
SET XACT_ABORT ON
BEGIN TRY
--Stored procedure logic
BEGIN TRY
BEGIN TRANSACTION;
--Transaction logic
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK;
THROW;
END CATCH
--More stored procedure logic
END TRY
BEGIN CATCH
--Handle errors gracefully
END CATCH
이 중 어떤 것도 도움이 되지 않았으므로 여기서 제 문제를 해결했습니다.팀 동료가 DDL 변경 사항을 모니터링하기 위해 서버 트리거를 구성했습니다.일단 비활성화하면 패키지를 설치할 수 있고 다시 활성화하면 패키지가 계속 작동합니다.
절차에서 정확히 동일한 오류가 있었습니다.이를 실행하는 사용자(우리의 경우 기술 사용자)는 임시 테이블을 만들 수 있는 권한이 충분하지 않은 것으로 드러났습니다.
EXEC sp_add 역할 구성원 'db_ddladmin', 'username_here';
속임수를 썼습니다
언급URL : https://stackoverflow.com/questions/7488149/sql-transaction-error-the-current-transaction-cannot-be-committed-and-cannot-su
'bestsource' 카테고리의 다른 글
서브라임 텍스트 2에서 열었을 때 XML 파일을 자동으로 들여쓰기 하는 방법은? (0) | 2023.09.11 |
---|---|
cURL을 사용하여 HTTPS 사이트에 연결할 수 없습니다. 대신 0 길이의 컨텐츠를 반환합니다.어쩌죠? (0) | 2023.09.11 |
xlib의 XNextEvent 차단을 중지하는 방법 (0) | 2023.09.11 |
MariaDB의 열 값을 다른 테이블에서 바꾸기 (0) | 2023.09.11 |
liquibebase를 사용하여 DB의 기존 행을 업데이트 할 수 있습니까? (0) | 2023.09.11 |