views:

36

answers:

1

I have the necessity for a client application to "lock" (aka "check-out" certain business entities store in the database.

The workflow is such that:

  1. The user navigates to a page for some business object.

  2. The user hits "edit".

  3. This locks the item from being edited by anyone else.

  4. Other users on other workstations will see a little "lock" icon by the item being edited and the "edit" button will be read-only.

  5. Admin users may click a button to "force" unlocking the item.

Pretty standard, right? I've done this a bunch of times in the past and I'm looking for some thoughts on the "right" way of doing this this time...

Namely, I guess there are two approaches:

  1. Have my business objects implement some ILockable interface which has a LockOwnerId property and have the corresponding table in the DB have that same LockOwnerId.

  2. Have a centralized "EntityLocks" table in the DB that manages all entity-type/primary key pairs of entities that are currently locked/checked out.

As for the API for acquiring a lock, I'm simply thinking of something along the lines of a CheckOut method:

// Returns true if the check-out was successful, 
// false if the check-out was not successful, becase the item was already locked. If 
// force is set to true, will check out the toCheckOut to the current user, regardless 
// of existing check-outs.
bool CheckOut(object toCheckOut, bool force)

Thoughts?

Thanks.

+1  A: 

Personally, I usually try to stay away from this pattern if I can, by requesting the business processes to be changed. This however, is not always possible and for this reason Martin Fowler described it as an actual pattern..

The solution you described sounds fine. However, I rather let the CheckOut method throw an exception except returning a bool. This is much more explicit. When developers forget to handle this exceptional case (the item could not be checked out) the error will be much easier to spot (because the exception isn't caught).

Also, please take good care of the implementation of the CheckOut method. Make sure it is transactional. The last thing you want is the possibility that two users both got a lock on the same object, because the implementation isn't implemented correctly.

Good luck.

Steven