From: trubar a on
I apologize for replying so late.

On May 14, 1:08 am, Erland Sommarskog <esq...(a)sommarskog.se> wrote:
>
> > * Also, I’m not sure I understand your reasoning on why we should roll
> > back regardless of whether SP was called from within a transaction or
> > not.
>
>
> If we were called from a transaction, we should roll it back, because
> we can no longer guarantee that we are able to fulfil our contract,
> and we don't want to leave the database in an inconsistent state.
>

Assuming stored procedure A calls stored procedure B and assuming
error occurs within B, then won’t what you suggest ( thus rolling back
inside B’s CATCH block ) make the two SPs tightly coupled, since now A
won’t have a chance to decide by itself whether or not it wants to
abort the transaction? I realize only other option would be for B to
use save points, which you said is a bad design, but isn’t making SPs
tightly coupled also a bad design?

> > then
>
> >  IF @@trancount > 0
> >         ROLLBACK TRANSACTION
>
> > will throw an error within a CATCH block – why would we want that?
>
> No, the error is raised when the procedure exits. In any case, an
> error has already occurred, and the show is over. Any extra error
> message is on the noise on the wire,

Yeah, but if B just raises an error, then @@trancount doesn’t get set
to back zero, while with B rolling back the transaction also sets
@@trancount to zero.


> A batch-aborting error will be caught in the CATCH handler, but the transaction will be
> "doomed", and you can only roll it back.

a) Are you sure that batch-aborting error will be caught by CATCH
handler? Namely, I did the following query and it appears that as soon
as batch aborting error was encountered, transactions were immediately
rolled back and then batch got aborted, and thus it appears that CATCH
block didn’t have a chance to run:

select convert(datetime, '20080230')
print 'This prints'

begin try
begin transaction
select convert(datetime, '2080230')
print 'This does not print'
commit
end try
begin catch
select @@TRANCOUNT
rollback
end catch

b) Anyways, what's the point of batch aborting errors abort the batch
even if they are thrown within TRY-CATCH blocks?


>
> > * BTW – you did say in one of your earlier posts that we should let
> > the transaction slip – what exactly did you mean by that?
>
> Do you have the context where I said it?
>

Here's your quote:

"Yes. But what I'm saying is that most of the time we don't care, but
if there is an error, we let the entire transaction slip. That's want
you want in most cases, so the complexity to deal with savepoints
every time is not worth it. "

thanx
From: Erland Sommarskog on
trubar a (asponmynet(a)gmail.com) writes:
> Assuming stored procedure A calls stored procedure B and assuming
> error occurs within B, then won�t what you suggest ( thus rolling back
> inside B�s CATCH block ) make the two SPs tightly coupled, since now A
> won�t have a chance to decide by itself whether or not it wants to
> abort the transaction? I realize only other option would be for B to
> use save points, which you said is a bad design, but isn�t making SPs
> tightly coupled also a bad design?

Not really. That is more a general pattern. "If you call a stored
procedure, it may run into an error where it must roll back the
transaction". Keep in mind that there is a vast difference between
COMMIT and ROLLBACK. COMMIT is the normal flow. ROLLBACK usually only
happens on the exception path.

> a) Are you sure that batch-aborting error will be caught by CATCH
> handler?

Yes. (OK, so I've seen a few exceptions, but they are very rare.)

> Namely, I did the following query and it appears that as soon
> as batch aborting error was encountered, transactions were immediately
> rolled back and then batch got aborted, and thus it appears that CATCH
> block didn�t have a chance to run:
>
> select convert(datetime, '20080230')
> print 'This prints'
>
> begin try
> begin transaction
> select convert(datetime, '2080230')
> print 'This does not print'
> commit
> end try
> begin catch
> select @@TRANCOUNT
> rollback
> end catch

When I run this, I get this output:

-----------------------
Msg 242, Level 16, State 3, Line 2
The conversion of a char data type to a datetime data type resulted in an
out-of-range datetime value.

This prints

-----------------------

(0 row(s) affected)


-----------
1

(1 row(s) affected)


The last result set is the "SELECT @@trancount" in the CATCH handler.

> b) Anyways, what's the point of batch aborting errors abort the batch
> even if they are thrown within TRY-CATCH blocks?

Beats me. Backwards compatibility, I guess. Error handling in SQL Server
is really confusing some times.

>> > * BTW � you did say in one of your earlier posts that we should let
>> > the transaction slip � what exactly did you mean by that?
>>
>> Do you have the context where I said it?
>
> Here's your quote:
>
> "Yes. But what I'm saying is that most of the time we don't care, but
> if there is an error, we let the entire transaction slip. That's want
> you want in most cases, so the complexity to deal with savepoints
> every time is not worth it. "

What I have been saying: in case of an error, we roll back the entire
transaction.

--
Erland Sommarskog, SQL Server MVP, esquel(a)sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
SQL 2000: http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

From: trubar a on
hi

Assuming stored procedure B is called from within a transaction and
assuming B also opens a new transaction, then if B rolls back the
transaction, then two things happen:
• the whole transaction is rolled back
• an error is raised ( due to rollback command setting @@trancount to
zero )

a) But is the whole transaction rolled back due to an error being
raised ( thus is an error a batch aborting transaction ) or due to
rollback command issued within B? I’m asking this since this error is
being raised when B exits, which is before the rollback command
( issued inside B ) has a chance to finish rolling back the whole
transaction.


On May 21, 2:49 pm, Erland Sommarskog <esq...(a)sommarskog.se> wrote:
> trubar a (asponmy...(a)gmail.com) writes:
> > Namely, I did the following query and it appears that as soon
> > as batch aborting error was encountered, transactions were immediately
> > rolled back and then batch got aborted, and thus it appears that CATCH
> > block didn’t have a chance to run:
>
> >    select convert(datetime, '20080230')
> >    print 'This prints'
>
> >    begin try
> >      begin transaction
> >        select convert(datetime, '2080230')
> >        print 'This does not print'
> >      commit
> >    end try
> >    begin catch
> >      select @@TRANCOUNT
> >      rollback
> >    end catch
>
> When I run this, I get this output:
>
>    -----------------------
>    Msg 242, Level 16, State 3, Line 2
>    The conversion of a char data type to a datetime data type resulted in an
>    out-of-range datetime value.
>
>    This prints
>
>    -----------------------
>
>    (0 row(s) affected)
>
>    -----------
>    1
>
>   (1 row(s) affected)
>
> The last result set is the "SELECT @@trancount" in the CATCH handler.
>

But then why doesn’t the result of "SELECT @@trancount" get displayed?


thanx
From: Erland Sommarskog on
trubar a (asponmynet(a)gmail.com) writes:
> Assuming stored procedure B is called from within a transaction and
> assuming B also opens a new transaction, then if B rolls back the
> transaction, then two things happen:
> � the whole transaction is rolled back
> � an error is raised ( due to rollback command setting @@trancount to
> zero )
>
> a) But is the whole transaction rolled back due to an error being
> raised ( thus is an error a batch aborting transaction ) or due to
> rollback command issued within B? I�m asking this since this error is
> being raised when B exits, which is before the rollback command
> ( issued inside B ) has a chance to finish rolling back the whole
> transaction.

Not sure what you mean here, but if B includes

ROLLBACK TRANSACTION
RETURN

The entire transaction is rolled back before RETURN is executed. At which
point error 266 will be raised.


--
Erland Sommarskog, SQL Server MVP, esquel(a)sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
SQL 2000: http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

From: trubar a on
hi

I really appreciate all your help and I also apologize for keep
dragging this thread for so long. Anyways, time to wrap it up

On May 27, 3:11 pm, Erland Sommarskog <esq...(a)sommarskog.se> wrote:
> trubar a (asponmy...(a)gmail.com) writes:
> > Assuming stored procedure B is called from within a transaction and
> > assuming B also opens a new transaction, then if B rolls back the
> > transaction, then two things happen:
> > • the whole transaction is rolled back
> > • an error is raised ( due to rollback command setting @@trancount  to
> > zero )
>
> > a) But is the whole transaction rolled back due to an error being
> > raised ( thus is an error a batch aborting transaction ) or due to
> > rollback command issued within B?  I’m asking this since this error is
> > being raised when B exits, which is before the rollback command
> > ( issued inside B ) has a chance to finish rolling back the whole
> > transaction.
>
> Not sure what you mean here,

I didn’t think it was possible for rollback command issued inside B
to rollback the entire transaction prior to procedure B exiting.
In other words, if we assume transaction which called B is inside
scope S1, while transaction started within B is inside scope S2, then
I thought that rollback command issued within B would first rollback
only the transaction started within scope S2, then it would have to
wait for B to exit, and only after B exits would it be able to also
rollback the main transaction ( which was started within scope S1 )





> --
> trubar a (asponmy...(a)gmail.com) writes:
> > Namely, I did the following query and it appears that as soon
> > as batch aborting error was encountered, transactions were immediately
> > rolled back and then batch got aborted, and thus it appears that CATCH
> > block didn’t have a chance to run:

> > select convert(datetime, '20080230')
> > print 'This prints'

> > begin try
> > begin transaction
> > select convert(datetime, '2080230')
> > print 'This does not print'
> > commit
> > end try
> > begin catch
> > select @@TRANCOUNT
> > rollback
> > end catch

> When I run this, I get this output:

> -----------------------
> Msg 242, Level 16, State 3, Line 2
> The conversion of a char data type to a datetime data type resulted in an
> out-of-range datetime value.

> This prints

> -----------------------

> (0 row(s) affected)

> -----------
> 1

> (1 row(s) affected)
> The last result set is the "SELECT @@trancount" in the CATCH handler.

But then why doesn’t the result of "SELECT @@trancount" get displayed?

thanx
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6
Prev: if statement
Next: SQL Server Performance Local vs Remote.