6 Replies Latest reply on Aug 5, 2004 4:29 AM by morenito9000

    Lock and immediate rollback of a transaction

    morenito9000

      Hi all,
      I'm using entity beans placed inside a "Standard CMP 2.x EntityBean"
      Container.
      For this container the default locking policy is:
      QueuedPessimisticEJBLoad.

      With 2 clients that try to use the same entity bean,
      the behaviour I see is that the Client I run for second
      must wait until the end of Client 1's transaction,
      before it can proceed.

      Question is:
      If I wanna the immediate rollback of Client 2 transaction
      if another client is using the "shared" entity bean
      which locking policy I must use ?

      QueuedPessimisticEJBLock is not good, but I think
      (I hope I'm wrong) that NoLock or JDBCOptimisticLock or
      SimpleReadWriteEJBLock are not good too :-(

      Many thanks in advance
      Moreno

        • 1. Re: Lock and immediate rollback of a transaction
          invisiblemage

          just wondering why you would like that behaviour ???

          • 2. Re: Lock and immediate rollback of a transaction
            morenito9000

            I need this behaviour because I wanna avoid this situation:

            CLIENT 1 starts modifying some data:
            it reads data, updates them (using a GUI) and writes them in the DB.

            if CLIENT 2 starts after CLIENT 1's start, but before CLIENT 1's update,
            it can try to write in DB "no more valid" data

            I prefer that CLIENT 2 is not allowed to start if there is
            another transaction that is managing the same data.

            Hi,
            Moreno

            • 3. Re: Lock and immediate rollback of a transaction
              invisiblemage

              So, are we talking of "real" clients, that read some data, display it to the user, and after 20 minutes the user commits new data?

              Then it is really no good practice to keep the entity-reference on the client (with a transaction open ?!!) - the client should never ever have direct access to an entity bean.
              instead, implement some VO-Pattern here.

              To avoid the situation "last one wins", i would just manually keep locking information somewhere that says "another using is editing this data, please try again later". (simply create a table with user/pk information or use a synchronized singleton)

              By the way, if you have the entity-reference on the client: client2 will not even be allowed to read the data if client 1 has placed a lock on it (open transaction, default behaviour), so client2 can not even display the data.

              summary: do not use entity beans to synchronize client interfaces!

              • 4. Re: Lock and immediate rollback of a transaction
                morenito9000

                invisiblemage wrote:

                >So, are we talking of "real" clients, that read some data, display it to the user, and after 20 minutes the user commits new data?

                Yes.

                >Then it is really no good practice to keep the entity-reference on the client (with a transaction open ?!!) - the client should never ever have direct access to an entity bean.
                instead, implement some VO-Pattern here.

                I followed the Session Facade Pattern.
                Clients use a Stateful Session Bean to change DB data.
                This could be the flow:

                1) The Client calls a method of the SFSB to lock the data.
                2) The SFSB sends data to client.
                3) The "human client" modifies (or adds) data using a GUI.
                4) The Client calls a method of the SFSB to commit data.

                In a first time I thought to start transaction only at point 4),
                but I have a problem.
                Different clients can modify data only when data are in a "particular state".
                If client1 starts modifying data (it can do it) and then client2 starts too and commit data before client1, then client1, according the
                new "state" of the data, couldn't be allowed to go on modifying.
                For this reason I'd like to stop immediately client2.

                >To avoid the situation "last one wins", i would just manually keep locking information somewhere that says "another using is editing this data, please try again later". (simply create a table with user/pk information or use a synchronized singleton)

                But in this case I must lock the "user/pk" table instead of
                "my data" table: where is the difference ?

                >By the way, if you have the entity-reference on the client: client2 will not even be allowed to read the data if client 1 has placed a lock on it (open transaction, default behaviour), so client2 can not even display the data.

                Yes, but I don't want client2 waiting for the end of client1's transaction.
                I would like an immediate end of client2 operations.

                Many thanks
                Moreno

                • 5. Re: Lock and immediate rollback of a transaction
                  invisiblemage

                  >>But in this case I must lock the "user/pk" table instead of
                  >>"my data" table: where is the difference ?

                  You do the following:


                  (Server Code)
                  try {
                  locktable.findByUserLock(user,row_to_lock);
                  return false;
                  } catch (FinderException e) {
                  insert(user,row_to_lock); // can only be inserted of not exists
                  }

                  Since this happens in one transaction on the server, only one client can get that lock. (the second client has to wait until this transaction is finished, so findByUserLock will not result in a finderexception)

                  If you receive the lock, you can savely read the data, and later, in another transaction, save the updated data.


                  Client "Code":
                  boolean ok = business.insertLock(user,row_to_lock); // only during this function call client 2 has to wait;

                  if (ok) { // client 2 will receive a false here
                  read_for_update();
                  } else { print("row is locked"); }

                  ... some user processing...
                  ... // NO TRANSACTION OPEN HERE! but we have the lock...
                  ...
                  on_save: write_update(); removeLock(user,row_to_lock);

                  The lock-table is only locked during setting the lock (or trying to), but not during showing and editing the data. In fact, you only have four short transactions during (1) lock (2) read (3) update (4) release lock.
                  But since setting the lock happens in a transaction, only one client can get that lock.

                  You even don't need a stateful session bean here, since you can give the userid with every call; by no means keep the transaction open during client calls!

                  • 6. Re: Lock and immediate rollback of a transaction
                    morenito9000

                    Thank you invisiblemage,
                    I'll try to adapt your example to my problem.

                    Moreno