Handle Concurency Problems.

4 posts, 2 answers
  1. Wolfgang
    Wolfgang avatar
    98 posts
    Member since:
    Oct 2012

    Posted 04 Jul 2014 Link to this post

    Hi, 

    we are still using openaccess classic.

    The application is mutlithreaded and uses different ObjectScopes.
    One common problem is that a background thread (or even another process) can compute objects. The user can access the object in the meantime resulting sometimes in an OptimisticVerificationException.
    In this case user changes something (lets say corrected an address) while a backgroudn job computed other values.

    We want the following behaviour: 
    Changes should not be lost. If user changes something, the "something" should be applied to the object.

    E.g. Lets say the background process computes a material property like density and user changes the materials name we want in case of concurency that
    - both changes are done. (e.g. if density is changed first and  OptimisticVerificationException appears density should be saved AND new name should be saved)
    - if multiple processes change the same propery - the last one should always win.

    If we do an Transaction.Commit() and the OptimisticVerificationException appears it seems that changes are lost. (Transaction.GetDirtyObjects no longer has any changes).

    Is there a generic way to 
    - preserve all changes and make a Refresh of an object not changing Properties which are changed in current transaction
    - preserve all changes even if an OptimisticVerifivationException occurs to do the Refresh in a loop?

    Best regards,
    Wolfgang

  2. Answer
    Ady
    Admin
    Ady avatar
    588 posts

    Posted 04 Jul 2014 Link to this post

    Hello Wolfgang,

     You can achieve what you want but its slightly tricky with the 'Classic API'
    1. Since the API is exposed on the OpenAccessContext you would first need to obtain the appropriate reference. You should case the objectScope as follows -  
      IExtendedObjectScope extendedScope = (IExtendedObjectScope )objectScope;
    2. In the exception handler you should first get the list of conflicted objects
      var conflictedObjects = extendedScope.GetLastConflicts().Select(c => extendedScope.GetObjectByKey(c.FailingObject));
    3. You then need to refresh these objects and specify the appropriate RefreshMode. Since the Refresh method is defined in the OpenAccessContextBase class you can just use the same code and create an extension method for the IObjectScope interface.
      public static void Refresh(this IObjectScope scope, RefreshMode mode, object entity)
      {
          switch (mode)
          {
              case RefreshMode.OverwriteChangesFromStore:
                  scope.Refresh(entity);
                  break;
              case RefreshMode.PreserveChanges:
                  scope.Retrieve(entity, new FetchPlan(new string[] { FetchPlan.All }, 1, FetchPlan.NoLimit));
                  break;
              default:
                  throw new ArgumentException("mode", "RefreshMode value not supported");
          }
      }

    You can then try and commit your changes again.
    Hope this helps. Do get back in case you need further assistance.


    Regards,
    Ady
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  3. DevCraft banner
  4. Wolfgang
    Wolfgang avatar
    98 posts
    Member since:
    Oct 2012

    Posted 07 Jul 2014 in reply to Ady Link to this post

    Hi Adi,

    what would be the difference to set 
    "Concurrency Control" - Verify by - to none?

    If i see the update statements correctly the last change would also win. Only without the slow Exception handling.

    Is there a drawback?

    Best regards,
    Wolfgang
  5. Answer
    Ady
    Admin
    Ady avatar
    588 posts

    Posted 09 Jul 2014 Link to this post

    Hi Wolfgang,

     As the name suggests 'None' means that no concurrency checks will be performed during an update. The drawback here is that you could overwrite intermediate changes to the object.

    Regards,
    Ady
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
Back to Top