I have ASP.NET MVC app and WCF Service.

Here is my code in MVC:


public ActionResult Service()
{
    var filterRepository = new FilterRepository();
    var idFilter = 78005;
    var filter = filterRepository.GetById(idFilter);

/* 1) We need such code:

    var resultLineViews = new ResultLineViewRepository().GetByIdFilter(idFilter);
    resultLineViews.ToList().ForEach(z => z.Remove());
*/

/* 2) or something else

    var filter1 = filterRepository.GetById(idFilter);
    filter1.HasTotals = !filter1.HasTotals;

*/
var client = new WinService.CalculatorFacadeClient();

client.Calculate(1, idFilter);

// 3) we can send another idFilter
//client.Calculate(1, 132);
client.Close();

return RedirectToAction("Index");

}

client.Calculate() calls method Calculate inside service, and the service is hosted in Windows Application, so we have two separated domains.

client.Calculate() calls this method:


private FilterInfo GetFilterInfo(int id)
{
    FilterInfo userSettings = null;

var sessionConfiguration = new SessionConfiguration(SessionOptions.AutoActivation){};

using (var session = Program.Domain.OpenSession(sessionConfiguration))
{

    using (var transactionScope = session.OpenTransaction())
    {
        /// 4) ------------ on this line we can get EXCEPTION, if 1) or 2) is uncommented - TimeoutException.
        var filter = StaticStorage.FilterRepository.GetById(id);

        userSettings = new FilterInfo
        {
            IsTemporary = filter.IsTemporary
        };

        transactionScope.Complete();
    }

}
return userSettings;

}

It all works.

But if we uncomment 1) or 2) in first code block - we got exception on 4) in second code block.

There are two different domains and application contexts, because first method invoked by MVC, second - by WinApp.

First code block runs inside transaction and opened session (Xtensive.Practices.Web.SessionManager).

That exception throws even if we put 3) instead of above line. So we have some table lock, maybe.

Any ideas?

asked May 31 '11 at 09:33

Ness's gravatar image

Ness
155232328

edited May 31 '11 at 09:33

Which transaction isolation level you use? Is it repeatable read? The case looks like a table lock.

(May 31 '11 at 09:53) Dmitri Maximov Dmitri%20Maximov's gravatar image

We use Xtensive.Practices.Web.SessionManager for ASP.NET MVC.

But only in this case we got problem, so I don't know, which isolation level is used by SessionManager :)

(May 31 '11 at 10:44) Ness Ness's gravatar image

What FilterRepository.GetById(id) does? It is called from both places.

BTW, could you send a sample or a real app so we could debug the issue instead of guessing? This could drastically shorten the time required for issue resolving.

(May 31 '11 at 11:14) Dmitri Maximov Dmitri%20Maximov's gravatar image

Sorry, but app is commercial, so I can't share it's sources.

GetById - it's something like this:


Session.Demand().Query.All<filter>().FirstOrDefault(f => f.Id == id);

And doesn't matter, what we do in Service() - making another query except filterRepository.GetById(idFilter), 1) or 2), leads to exception in 4)

(May 31 '11 at 11:59) Ness Ness's gravatar image

OK, I see. Then let's try solving the issue in the Q/A mode. Could you grab the output of SQL Profiler so we could analyze what queries are being executed on the server? Thanks.

(May 31 '11 at 13:28) Dmitri Maximov Dmitri%20Maximov's gravatar image

Seems it is expected timeout. You are changing filter instance within one transaction and trying to read the same instance within another one. So attempt to read locked instance is timing out as it must be. As an option you can try to switch isolation level to Snapshot or ReadCommitted+Snapshot. Or try not to change filter.

(May 31 '11 at 13:56) Alex Ustinov Alex%20Ustinov's gravatar image

Additionally if you need to access changed filter in context of Calculate method you in a trouble because you need to commit to make changes visible but SessionManager controls transaction by its own. In this case filter settings may be sent as Calculate method parameters

(May 31 '11 at 13:58) Alex Ustinov Alex%20Ustinov's gravatar image

Ok, I understand.

We forgot, that SessionManager opens transaction, so we were surprised by such behavior.

Thanks.

(Jun 01 '11 at 04:32) Ness Ness's gravatar image

Hi Ness

Can we consider my comments as an answer?

If so I'd copy the text as reply to make you able to accept it and close question.

Btw, did you find an approach to avoid locking?

(Jun 03 '11 at 02:44) Alex Ustinov Alex%20Ustinov's gravatar image
1

Yes, Alex.

We found approach - we moved method to service, so MVC method doesn't use database.

(Jun 03 '11 at 05:06) Ness Ness's gravatar image

One Answer:

The answer is copied from the comments to original question.

Seems it is expected timeout. You are changing filter instance within one transaction and trying to read the same instance within another one. So attempt to read locked instance is timing out as it must be. As an option you can try to switch isolation level to Snapshot or ReadCommitted+Snapshot. Or try not to change filter.

Additionally if you need to access changed filter in context of Calculate method you in a trouble because you need to commit to make changes visible but SessionManager controls transaction by its own. In this case filter settings may be sent as Calculate method parameters

answered Jun 03 '11 at 05:24

Alex%20Ustinov's gravatar image

Alex Ustinov
2484

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