Is there any possibility to catch inner exception:
try
{
ttsbegin;
info("step one");
try
{
info("step two");
throw Error("error");
}
catch
{
info("catch step two");
}
ttscommit;
}
catch
{
info("catch step one");
ttsabort;
}
I know I can get it commenting ttsbegin; / ttscommit, but I need to have a transaction.
No, it is not possible (unless your exception is UpdateConflict
or DuplicateKeyException
).
The documentation states:
If an exception is thrown inside a transaction, the transaction is automatically aborted (a ttsAbort operation occurs). This applies both for exceptions thrown manually and for exceptions thrown by the system.
When an exception is thrown inside a ttsBegin - ttsCommit transaction block, no catch statement inside that transaction block can process the exception. Instead, the innermost catch statements that are outside the transaction block are the first catch statements to be tested.
The logic is: 1) your transaction is aborted by the throw 2) then you cannot possible recover from that inside your transaction 3) hence take the innermost catch outside the transaction.
The two exceptions (pun intended) are UpdateConflict
and DuplicateKeyException
which do not make a ttsabort
and hence may be caught inside the transaction.
Also see this blog entry which demonstrate that.
Update: Potential pitfall
Using catch all (no exception type specified) can cause problems. See this blog post.
As of D365O update 5 the the two exceptions are not caught by a catch all if the tts level is greater than one. See this blog post.
来源:https://stackoverflow.com/questions/12535992/how-to-catch-inner-exception