简体   繁体   中英

Implementing lock / edit / unlock with wcf service

I am implementing a service that lets users browse various objects, add new ones then save them, which is a pretty basic functionality. The service is provided via WCF and uses EF4 code first to access data of a SQL Server Database.

However there is a catch: There are certain rules which are supposed to let only one user work on one object at a time, hence the lock edit unlock behaviour mentioned in the title.

So lets say there is a filter that says "records with a timestamp between date X and date Y". Now a user locks this "filter" and is the only one who can add (note: not modify!) new records for the timerange between date X and date Y.

It is also worth noting that the filter is not a physical entity i can access since there are virtually unlimited possible filters to be had. A "select for update" / row lock is therefore not possible (i think!). Also, filters are only available in fixed timerange steps, so there is no overlapping of filters, though there is no limit on how far you can lock into the future (or past).

I have come up with a solution that works so far but i am not really happy with it. I prefer having the code in my service somewhere instead of implementing this in the database but any recommendation is welcome:

  • When a user requests a lock, i first check if there already is an object that conforms to the filter and has a "locked on" timestamp set. If there is, another lock is not possible. If not, i create a new record and save it to get a "handle" (some id) to this record for passing back to the client. Before i do that however i run the query again, and if i receive more than one record for the timerange that has the "locked on" timestamp set, the one with the eg highest id will count as the actual lock and all other records will be deleted. I dont think this is particularly clean so i dont really want to use it.

  • I also thought of using WCF operationcontract attributes to only allow a single call at any one time, but i dont like that either.

I'd recomend checking for an active filter either when a user attempts to select a filter, or when they attempt to save changes (selection makes for a better Ux). In order to determine the active filter you'll need to make sure the time step is not already in use, which can easily be accomplished like this:

public static class FilterMonitor { private static Dictionary steps = new Dictionary();

public static bool CheckActiveAddIfNew(TimeStep step)
{
    //Assumes synchronization logic
    bool isActive;
    if(!steps.TryGetValue(step, out isActive)
    {
       steps.Add(step, true);
       isActive = true;
    }
    return isActive;
}

public static bool ChangeFilter(TimeStep oldSetp, TimeStep newStep)
{
   //Synchronization code
   bool ableToChange;
   if(!CheckActiveAddIfNew(newStep))
   {
       steps[newStep] = true;
       steps[oldStep] = false;
       ableToChange = true;
   }

   return ableToChange;
}

}

Once a user is done with a filter they should release it and allow another user to acquire it if they want. This can be accomplished via something like the ChangeFilter method that only allows them to select the new filter if it has not already been selected by another user. This ensures that only one user can have access to a filter at any one time, preventing the case where multiple users will be adding/removing from the same filter.

If however you need multiple users to access the same TimeRange but only want to allow a single user to add/remove records to that range, simply replace the bool in the Dictionary w/ a User object that maps to one and only one user. This changes the logic from being a simple active/Inactive filter to active & owned by User1/ Inactive. Obviously only User1 will be allowed to Add records to that range.

Please let me know if you have any questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM