Hi, I create unique index (from my previous post) and try to add duplicate row and can't catch sqlException

    public override void ApplyChanges()
    {
        try
        {
            using (var transactionScope = Transaction.Open())
            {
                using (InconsistentRegion inconsistentRegion = Validation.Disable())
                {
                    base.ApplyChanges();
                    var entity = (Folder) GetEntity();
                    entity.Name= Name;
                    entity.Parent = Parent;
                    inconsistentRegion.Complete();
                }
                transactionScope.Complete();
            }
        } catch(Exception exception)
        {
            ;
        }
    }

but I catch it in global.asax Application_Error

PS: I use DataObjects.Net ASP.NET MVC example

asked Sep 16 '10 at 12:56

dj_raphael's gravatar image

dj_raphael
5224

edited Sep 17 '10 at 01:04

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412


One Answer:

If exception is really thrown inside this try-catch block, it will be caught here. Try to set breakpoint to check this.

On the other hand, your view may use the same Session (with locked transaction) further, and one more exception might be thrown there (note that the original error is suppressed by your catch block). So in this case you'll really see it in Application_Error.

How to fix the issue:

  1. First way is to replace Transaction.Open() to Transaction.Open(TransactionOpenMode.New). This will ensure the outermost transaction won't be locked in case of exception in your handler.

  2. Second way is to ensure view won't use the Session with locked transaction in case of error - e.g. by selecting special "error view.

  3. You can try to start a new outermost transaction by hacking SessionManager. This is possible, but you'll need to access its private members via reflection. In general, this is a bad idea - normally each web request is processed inside a single transaction.

  4. You can manually open new Session and transaction in your view in case of error, if this is really necessary. ~ The same case as 3, but without hacks.

Also note, that you can't catch SqlException directly. You must catch one of our high-level wrappers (DeadlockException, ConstraintViolationException, etc. - all of them are descendants of StorageException); original SqlException can be found by unwinding InnerException chain there.

answered Sep 17 '10 at 00:59

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

edited Sep 17 '10 at 01:08

Thanks you, replace Transaction.Open() to Transaction.Open(TransactionOpenMode.New) have solved a problem.

(Sep 17 '10 at 04:14) dj_raphael dj_raphael's gravatar image

Great then :) So my analysis was correct.

(Sep 17 '10 at 10:51) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA