Transacciones de ADO.NET y de SQL

21/06/2007 - 18:02 por Marianoh | Informe spam
Hola a todos:

Tengo una serie de sp's que tienen varias sentencias que deben
estas transaccionadas, pero estos sps se pueden llamar con o sin una
transaccion abierta desde ADO.NET.

Viendo que ROLLBACK dehace todas las transacciones abiertas y
COMMIT confirma la última transacción abierta,

¿esta bien el siguiente código?

DECLARE @TRANCOUNT_INICIAL INT
SET @TRANCOUNT_INICIAL = @@TRANCOUNT

INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
...
ELSE
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
COMMIT TRAN
END

Gracias.

Preguntas similare

Leer las respuestas

#1 Federico A Colli
21/06/2007 - 18:56 | Informe spam
Hola.
Compo desarrollador te puedo decir que las transacciones en el código (por
ejemplo VB) y las de los Sp son independientes, en realidad si ejecutas un
ROLLBACK a nivel de codigo se hara un rollback completo, pero si usas
transacciones en los SP estas estan en un ambito inferior, por lo que un
rollback dentro de estos solo afectará a la transaccion que se abrió denro
del SP.
Básicamente es un anidamiento de la forma:

Codigo app
Begin trans
|
|
| => Execute sp_XXX
Begin
|
|
|
|
| <= Rollback/Commit => Este rollback afecta a la
transaccion del SP
|
|
Rollback/Commit => Este rollback afecta la ejecucion completa del SP y
de lo que se haya ejecutado (desde el
codigo) antes o desdes del SP

Carpe diem, tempus fugit.
El hombre sabio no da las respuestas correctas, propone las preguntas
correctas (Claude Levi-Strauss).
La sabiduría no es un producto de la educación sino de toda una vida por
adquirirla (Albert Einstein).
El sabio puede sentarse en un hormiguero, pero sólo el necio se queda
sentado en él (Proverbio chino).

AUS Federico A. Colli


"Marianoh" escribió en el mensaje
news:
Hola a todos:

Tengo una serie de sp's que tienen varias sentencias que deben
estas transaccionadas, pero estos sps se pueden llamar con o sin una
transaccion abierta desde ADO.NET.

Viendo que ROLLBACK dehace todas las transacciones abiertas y
COMMIT confirma la última transacción abierta,

¿esta bien el siguiente código?

DECLARE @TRANCOUNT_INICIAL INT
SET @TRANCOUNT_INICIAL = @@TRANCOUNT

INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
...
ELSE
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
COMMIT TRAN
END

Gracias.
Respuesta Responder a este mensaje
#2 Miguel Egea
22/06/2007 - 00:48 | Informe spam
Federico, eso no es cierto, es cierto con commit pero JAMÁS con Rollback.

un rollback deja @@trancount a 0, y si no produces un errror para que tus
aplicaciones lo catcheen podrás estar liando una buena en tus apps.

Aunque creo que el código tiene algún bug (hace rollback 2 veces y
seguramente falle en algunas ocasiones) aqúi tienes algo de como debería ir
tu código
http://www.4guysfromrolla.com/webte...postadlink

Intento explicar lo que pasa, este código

create table t (id int)
go

create procedure a as
begin
begin tran
insert into t (id) values (1)
rollback
end
go
begin tran
select @@trancount
exec a
select @@trancount
insert into t (id) values (2)
rollback
go
select * from t

insertará un 2 en la BBDD ¡A PESAR DE TU ROLLBACK¡ , simplemente porque el
sp hace un rollback, pero no un raiserror, así que al terminar de
ejecutarse a, @@trancount vale 0 (a pesar del begin tran que ejecutamos
antes) y como no se ha producido ningún error, el siguiente comando se
ejecuta dentro de una transacción implicita que es validada inmediatamtne, y
el rollback no sirve para nada, quedandose insertado tu valor 2 en la tabla.

así pues el control de errores ha de ser mucho más fino, en 2005 podría
quedar algo así

prueba este código
delete from t
go
alter procedure a as
begin
begin tran
insert into t (id) values (1)
rollback
return @@error
end
go

declare @res int

select @@trancount
begin try
begin tran
exec @res=aa
insert into t (id) values (2)
commit
end try
begin catch
if @@trancount!=0
rollback
raiserror ('Se produjo un error ',16,1)
end catch
go
select * from t




Saludos.

Miguel Egea

"Federico A Colli" wrote in message
news:
Hola.
Compo desarrollador te puedo decir que las transacciones en el código (por
ejemplo VB) y las de los Sp son independientes, en realidad si ejecutas un
ROLLBACK a nivel de codigo se hara un rollback completo, pero si usas
transacciones en los SP estas estan en un ambito inferior, por lo que un
rollback dentro de estos solo afectará a la transaccion que se abrió denro
del SP.
Básicamente es un anidamiento de la forma:

Codigo app
Begin trans
|
|
| => Execute sp_XXX
Begin
|
|
|
|
| <= Rollback/Commit => Este rollback afecta a la
transaccion del SP
|
|
Rollback/Commit => Este rollback afecta la ejecucion completa del SP y
de lo que se haya ejecutado (desde el
codigo) antes o desdes del SP

Carpe diem, tempus fugit.
El hombre sabio no da las respuestas correctas, propone las preguntas
correctas (Claude Levi-Strauss).
La sabiduría no es un producto de la educación sino de toda una vida por
adquirirla (Albert Einstein).
El sabio puede sentarse en un hormiguero, pero sólo el necio se queda
sentado en él (Proverbio chino).

AUS Federico A. Colli


"Marianoh" escribió en el mensaje
news:
Hola a todos:

Tengo una serie de sp's que tienen varias sentencias que deben
estas transaccionadas, pero estos sps se pueden llamar con o sin una
transaccion abierta desde ADO.NET.

Viendo que ROLLBACK dehace todas las transacciones abiertas y
COMMIT confirma la última transacción abierta,

¿esta bien el siguiente código?

DECLARE @TRANCOUNT_INICIAL INT
SET @TRANCOUNT_INICIAL = @@TRANCOUNT

INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
INSERT/UPDATE...
IF @@ERROR <>0
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
ROLLBACK TRAN
RETURN @@ERROR
END
...
ELSE
BEGIN
IF @@TRANCOUNT > @TRANCOUNT_INICIAL
COMMIT TRAN
END

Gracias.



email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida