tiene - transacciones en sql server pdf
El recuento de transacciones después de EXECUTE indica un número incorrecto de instrucciones BEGIN y COMMIT. Recuento previo=1, conteo actual=0 (11)
Asegúrese de no tener múltiples transacciones en el mismo procedimiento / consulta, de las cuales una o más quedan sin compromiso.
En mi caso, accidentalmente tenía una declaración BEGIN TRAN en la consulta
Tengo un Procedimiento de inserción almacenado que alimentará los datos a la Tabla1 y obtendrá el valor de Columna1 de la Tabla1 y Llamar al Segundo Procedimiento Almacenado que alimentará la Tabla2.
Pero cuando llamo al segundo procedimiento almacenado como:
Exec USPStoredProcName
Me da error de la siguiente manera:
El recuento de transacciones después de EXECUTE indica un número incorrecto de instrucciones BEGIN y COMMIT. Recuento previo = 1, conteo actual = 0.
He leído las respuestas en otras preguntas similares y no puedo encontrar dónde exactamente se está arruinando el recuento de compromisos.
En mi opinión, la respuesta aceptada es en la mayoría de los casos una exageración.
La causa del error a menudo no coincide con BEGIN y COMMIT, tal como lo establece claramente el error. Esto significa usar:
Begin
Begin
-- your query here
End
commit
en lugar de
Begin Transaction
Begin
-- your query here
End
commit
¡omitir la transacción después de comenzar causa este error!
Esto normalmente ocurre cuando la transacción se inicia y no se confirma o no se revierte.
En caso de que el error ocurra en su procedimiento almacenado, esto puede bloquear las tablas de la base de datos porque la transacción no se completa debido a algunos errores de tiempo de ejecución en ausencia de manejo de excepciones. Puede usar el manejo de excepciones como se indica a continuación. SET XACT_ABORT
SET XACT_ABORT ON
SET NoCount ON
Begin Try
BEGIN TRANSACTION
//Insert ,update queries
COMMIT
End Try
Begin Catch
ROLLBACK
End Catch
Source
Esto también puede ocurrir si su procedimiento almacenado encuentra un error de compilación después de abrir una transacción (por ejemplo, tabla no encontrada, nombre de columna no válido).
Descubrí que tenía que usar 2 procedimientos almacenados, uno de "trabajador" y uno de envoltura con try / catch, ambos con lógica similar a la descrita por Remus Rusanu. La captura de trabajador se usa para manejar las fallas "normales" y la captura de contenedor para manejar errores de compilación de fallas.
https://msdn.microsoft.com/en-us/library/ms175976.aspx
Errores no afectados por una construcción TRY ... CATCH
Los siguientes tipos de errores no son manejados por un bloque CATCH cuando ocurren en el mismo nivel de ejecución que la construcción TRY ... CATCH:
- Compila errores, como errores de sintaxis , que impiden la ejecución de un lote.
- Errores que ocurren durante la recompilación de nivel de sentencia, como los errores de resolución de nombre de objeto que ocurren después de la compilación debido a la resolución diferida del nombre.
Con suerte, esto ayuda a otra persona a ahorrar unas horas de depuración ...
Me encontré con este error una vez después de omitir esta declaración de mi transacción.
COMMIT TRANSACTION [MyTransactionName]
Para mí, después de una depuración exhaustiva, la solución era un simple lanzamiento perdido; declaración en la captura después de la reversión. Sin este feo mensaje de error es con lo que terminas.
begin catch
if @@trancount > 0 rollback transaction;
throw; --allows capture of useful info when an exception happens within the transaction
end catch
Si tiene un bloque TRY / CATCH, la causa probable es que esté atrapando una excepción de cancelación de transacción y continúe. En el bloque CATCH, siempre debe verificar el XACT_STATE()
y manejar las transacciones canceladas y no modificables (condenadas) apropiadas. Si la persona que llama inicia una transacción y la calee golpea, por ejemplo, un punto muerto (que abortó la transacción), ¿cómo va a comunicar el destinatario al llamante que la transacción fue abortada y no debe continuar con ''negocios normales''? La única manera factible es volver a plantear una excepción, obligando a la persona que llama a manejar la situación. Si traga silenciosamente una transacción cancelada y la persona que llama continúa asumiendo que todavía está en la transacción original, solo el caos puede garantizar (y el error que obtiene es la forma en que el motor intenta protegerse).
Te recomiendo que revises el manejo de excepciones y las transacciones anidadas, que muestran un patrón que se puede usar con transacciones anidadas y excepciones:
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
go
Si tiene una estructura de código de algo así como:
SELECT 151
RETURN -151
Luego usa:
SELECT 151
ROLLBACK
RETURN -151
También tuve este problema. Para mí, la razón fue que estaba haciendo
return
commit
en lugar de
commit
return
en un procedimiento almacenado.
Tenga en cuenta que si utiliza transacciones anidadas, una operación ROLLBACK revierte todas las transacciones anidadas, incluida la más externa.
Esto podría, con el uso en combinación con TRY / CATCH, provocar el error que describió. Ver más here .
Tuve el mismo mensaje de error, mi error fue que tenía un punto y coma al final de la línea COMMIT TRANSACTION