Discussions

EJB programming & troubleshooting: Locking in ejb

  1. Locking in ejb (3 messages)

    Hello All,
      Please provide me a solution for the below said info.

    This is rergarding locking of an record while in edit mode.
    Iam using an BMP which is called by state less bean, this inturn is called by Servlet.
    In My Client Page, I will list all the records in a table.
    when I select a record, I must Lock this record so that other user should not able to edit this record until I release this record.
    No database change should take place.
    My Main Question is with out changing Data Base, I want to Lock a record so that Other User cannot access same record until I release this record.
      So Pls suggest me as soon as possible

    Thanks
    BSREDDY

    Threaded Messages (3)

  2. Locking in ejb[ Go to top ]

    Hi Reddy,

    You'll need to use a transaction isolation level of TRANSACTION_REPEATABLE_READ. When you select the data you want to edit a lock will be put on the row within the database. This lock won't be released until your transaction commits. Therefore, any other session that tries to update the same row (or page or table, depending on the granuality of your database locks) will be put into a wait state until your EJB update executes and your commit or rollback is complete.

    To implement this within an EJB context you'll have to use a stateful session bean. This is because you'll have to use bean managed transaction demarcation at the session bean level. You'll need a stateful session bean as opposed to a stateless session bean as you'll need to keep a transaction open between invocations of the select and update methods. Having a stateful session bean shouldn't be too much of an issue for you as you could keep a reference to the bean within your HttpSession object.

    Your stateful session bean will need two methods: getData and setData (or something of the kind). Your getData method should obtain a transaction from your EJB server (javax.transaction.UserTransaction) and call begin(). Then obtain a connection interface from your connection pool and set its isolation level to Connection.TRANSACTION_REPEATABLE_READ and then grab your data and display it in your servlet.

    When your user hits the submit button, pass the changed data through to the setData method of your session bean which will execute the update and call commit() on the UserTransaction.

    That oughta do it. Note that your database performance will be hampered as keeping a lock on a row will stop other users from updating it, so keep your transactions as short as possible. Also, my experience of using isolation levels is that if you have a lock on a row for updating and another transaction tries to update and is put into a wait state, when you make your update statement your transaction will be killed due to a deadlock situation. However, one transaction would have to be killed!

    As a side note, another solution would be to access the entity bean directly from your servlet (ie: not via a session bean). However, this would entail setting the isolation level at the database level and not the transaction level which may not suit.

    Let me know how you get on.

    Cheers,
    Darren.
  3. Locking in ejb[ Go to top ]




    I would strongly advise that you DONT use transaction management to implement this. Transactions consume large amounts of resources - and as is suggested, it will impact performance significantly.

    The way to handle this is in the entity bean code. You have introduce a lock field in the entity bean (and therefore, database). This lock will allow reading but prevent updates by anyone who does not have the lock.

    The lock must also have an expiry (in case the user never commits and never comes back). This can be simply done by implementing the lock field as just a timestamp that . It is set when the "transaction" starts (when the user selects it for update) and updates are only performed when the matching timestamp is passed into the update method.

    ReadDTO readAndLock() {

      ReadDTO dto;
      // read data ...

      // check and set lock
      if (currentTime > lockTime + timeout) {
        lockTime = currentTime;
        dto.lockTimeStamp = lockTime;
      }
      else {
        throw new LockException("Already Locked");
      }

      return dto;
    }

    void updateAndCommit(WriteDTO dto) {

      // check user holds lock
      if (dto.lockTimeStamp != lockTime) {
        throw new LockException("Update Denied");
      }

      // update bean...

    }

    The other option is to use optimistic locking.
  4. Locking in ejb[ Go to top ]

    Reddy,

    I am not sure about locking a particular record only. As far i know, you can lock on the all rows of resultset but not on single row of the result set. If your query results only one row there is no problem but if it retrives few 10's of rows and locking time is more, it affect the performance.
    Let us know how you implemented this scenario.

    Thanks,
    Srinivas Gamini