2 Replies Latest reply on Jan 25, 2005 6:42 PM by Brian DeCamp

    Pessimistic locking with notification in EJB

    Steven Mayocchi Newbie


      We are working on a web application where the desired behaviour is as follows:

      1. User A locks a record and begins editing.
      2. User B attempts to lock the same record and immediately receives notification that the record is already locked.
      3. In the case of server crash or other failure User A's lock times out and the record then becomes available to all users.

      We are using EJB's with CMP. Our current mechanism for locking involves a centralised 'locking manager'. However this has issues with scalability that we need to address.

      What I am looking for are some decent alternatives given our desired behaviour.

      Thanks in advance!

        • 1. Re: Pessimistic locking with notification in EJB
          Bernd Zeitler Expert

          Just an idea: use a db as your 'locking manager'...?

          But you can even implement your own locking manager (perhaps as mbean, perhaps with an ejb facade) and deploy it as hasingleton when running with clustered jboss...

          • 2. Re: Pessimistic locking with notification in EJB
            Brian DeCamp Newbie

            We use the same pattern for pessimistic locking. Our implementation requires an extra timestamp column on the table with the row you'd like to lock. We also have a column for the ID of the user who is locking the row for user feedback.

            All access to this table (at least the lock columns) must be through an entity bean. Once the entity bean is active in a transaction, you are guaranteed it is not active in any other transactions, unless you mess up the concurrency modifiers for the container (be sure to test this). This allows you to perform an atomic test-and-set operation on the locking row. If the timestamp is null or expired, go ahead and set it for some time in the future (e.g. 20 minutes) granting that user the exclusive lock. Otherwise, fail and report back to the user that the row is in use (optionally, report who owns the lock). There are no singletons or central lock manager so you'll have all the scalability you want.

            You'll also want some way of releasing a lock before the expiration time, and we also allow a user to extend their exclusive access. We code defensively on the server side to be sure client applications can never extend or release a lock they don't actually own. It's not trivial, but it works well.

            The container's contract that an entity can only be active in a single transaction is the key. Otherwise, you'll end up with a race condition and start granting locks to multiple users in rare (and not easily reproducible) cases.

            A word of caution: if you access your entity bean outside a transaction, which I'm sure you would never do, but if you did, then you will not get the atomic behavior you're looking for. To guaranteed the entity is always accessed inside a transaction use trans-attribute=Mandatory in the ejb-jar.xml descriptor.

            Good luck!