Unable to initiate lock

2 posts, 0 answers
  1. IT
    IT avatar
    41 posts
    Member since:
    Jan 2010

    Posted 14 Jul 2011 Link to this post

    I have a forward only model mapped entirely using Fluent, and I'm trying to lock a collection without success.

    There aren't many examples out there, and few posts in the forum.

    Here's an example of how I'm setting up:-

    BackendConfiguration backendConfiguration = new BackendConfiguration();
    backendConfiguration.Backend = "mssql";
    Meta2.Context context = new Meta2.Context(connectionString, backendConfiguration);

    Then I'm trying something like this:-

    context.Scope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
    context.Scope.Transaction.Begin();
    context.Scope.Transaction.Lock(context.Scope.Extent<Accounts.Payable.Invoice>(), LockMode.WRITE);

    But I get "Telerik.OpenAccess.Exceptions.TransactionException: Transaction properties cannot be modified for active transactions." trying to set the concurrency. So I try a commit just before, to close the transaction:

    context.Scope.Transaction.Commit();
    context.Scope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
    context.Scope.Transaction.Begin();
    context.Scope.Transaction.Lock(context.Scope.Extent<Accounts.Payable.Invoice>(), LockMode.WRITE);

    Now I get: "Telerik.OpenAccess.Exceptions.TransactionException: The method Commit is not supported for managed transactions."

    OK.. I'll try flush then...

    context.Scope.Transaction.Flush();
    context.Scope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
    context.Scope.Transaction.Begin();
    context.Scope.Transaction.Lock(context.Scope.Extent<Accounts.Payable.Invoice>(), LockMode.WRITE);

    Now I get: "Telerik.OpenAccess.OpenAccessException: no active transaction"... hey?? didn't it just say there *was* a transaction?

    Usually I have a context I generate in a HttpModule, however trying using a new scope as in the example above makes no difference.

    Has anyone got a working example for this scenario?

    Currently using ORM 2011.2.713, but doesn't seem version dependent.
  2. Jan Blessenohl
    Admin
    Jan Blessenohl avatar
    707 posts

    Posted 14 Jul 2011 Link to this post

    Hi Aleks,
    You are right, this is a little tricky. The context starts a transaction immediately. This makes it impossible to change it later. You have to change the default for all contexts first.
    using (var ctx = new EntitiesModel())
    {
        ctx.Scope.Database.DefaultTransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
    }
    using (var ctx = new EntitiesModel())
    {
        foreach (var item in ctx.A_types)
        {
            ctx.Scope.Transaction.Lock(item, LockMode.DELETE);
        }
    }

    Be careful in multithreadding environments, maybe you have to put this into a locking block. Here is a second way, maybe the better one:

    using (var ctx = new EntitiesModel())
    {
        using (var tmp = new EntitiesModel())
        {
            var old = tmp.Scope.Database.DefaultTransactionProperties.Concurrency;
            tmp.Scope.Database.DefaultTransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
            var s = ctx.Scope;// this works because the real scope is generated lazy
            tmp.Scope.Database.DefaultTransactionProperties.Concurrency = old;
        }
        foreach (var item in ctx.A_types)
        {
            ctx.Scope.Transaction.Lock(item, LockMode.DELETE);
        }
    }


    Kind regards,
    Jan Blessenohl
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  3. DevCraft banner
Back to Top