7 Replies Latest reply on Jan 21, 2002 2:25 PM by cknoll

    Force JBoss to synchronize entity.

    woodspeaker

      Heya. Got a situation where I need to force JBoss to synchronize a CMP entity bean on demand. My situation presents an object whose corresponding row in persistence has been manually modified by a DB user. The cached object is now invalid, but the EJB's finder only returns the cached object. Lazy-read caching ( option D ) is not an solution since I don't want this EJB instance around forever. Options B, and C cost way too much performance with respect to this entity. Option A is out cuz the container is not the only thing modifying data persistence.
      Knowing whether the row has been modified can be easily done, its getting JBoss to read that data into memory that seems to be the problem. ( The above text refers to the bottom of chapter 7 in the online docs ).

        • 1. Re: Force JBoss to synchronize entity.
          vincent

          Maybe a combination of read-only timedout and commit-option B/C deployement of the same entity bean ?
          You use the second one when you want the very last version and the first one when you don't care.

          Else I don't see any solutions, commit-options B/C are there to solve this problem. What "problems" do you have with B/C ?

          • 2. Re: Force JBoss to synchronize entity.
            woodspeaker

            Thank you Vincent.
            The only issues I have with commit options B and C are the performance hit. Objects would be sychronized quite often via those two options.
            The object in question is an Order EJB. There are a lot of transactions occuring on the Order and its line items as they pass through processing ( validations on addresses, subtotals, totals, taxes, fees, compliance issues... ). So with either of these options I will incur a severe performance hit. Not unwarranted, in my view, but the proj architect isn't in favor of synchronizing via options B or C because of the # of transactions involved.
            My problem of synchronization arises when an EJB is accessed a second time before it is passivated. Example: an order is processed through the system and fails for some reason ( bad address, say ). A DB user fixes the address and queues up the order for reprocessing. If persistence has changed by the db user before the Order EJB passivates, reprocessing uses the cached EJB which reflects invalid data. The order fails again because the fixed address has not been read from persistence. Actually, once a business method is invoked on the Order, the bad address is re-persisted and the db user's work is undone. Funny eh?
            In short, I need to be very aware of exactly how long to keep EJBs around, and passivate them asap in order to minimize cases like this.
            JBoss / synchronization via standard methods can work, we just need to work on timing of our office processes.
            It'd be nice though if there were a way for an EJB to request the container to load it again.
            Interesting side note: EJB Spec [17.3.1]. If you write a method that throws a non-app exception, the container will discard the instance of the EJB that threw the exception. Catch it, of course. Then you can invoke the home interface's finder to load the same ejb, and you're pretty much guaranteed to get a fresh copy from persistence. Not advisable, but it'll be interesting to see if it works.

            • 3. Re: Force JBoss to synchronize entity.
              dsundstrom

              If you want to modify the entity from both JBoss and another location, you will have to use commit option B. Commit option A is all about assuming that database will only be modified by JBoss.

              I assume that you are not using CMP 1.1 (JAWS) because of the comment about commit option B being expensive. With CMP 1.1 (JAWS) you cna use a read-only entity, where the container synchronize after a timeout period.

              If you switch to CMP 2.0 in JBoss 3.0 alpha, you can use lazy loading. Assuming that the "this has changed column is cheap to load," you only eager load that column, and if it has changed you lazy load the rest into your private cache. If it has not changed, you just use your privately cached data. Of course need to send your application to productions soon this is not an option.

              What you really want is Commit Option B Optimistic Locking in CMP. With that before the container does a reload it checks to see if the row has changed. This is similar to the above scenario but it is handled by the container. This is on the todo list for 3.0 final, but it is not a top priority.

              • 4. Re: Force JBoss to synchronize entity.
                woodspeaker

                Thank you Dain.

                I'm pushing for CMP 2.0, and we'll undoubtedly move to JB 3.0 as soon as it is available as a release.

                If we cannot more smoothly orchestrate/schedule our processes so that they don't overlap on each other, then lazy/eager loading sounds like just what we need.

                Thank you again.

                • 5. Re: Force JBoss to synchronize entity.
                  vincent

                  What Dain says is very attractive for CMP 2.0 :-), but I would like to come back on what you say...

                  > Not unwarranted, in my view, but the proj architect
                  > isn't in favor of synchronizing via options B or C
                  > because of the # of transactions involved.
                  > My problem of synchronization arises when an EJB
                  > JB is accessed a second time before it is passivated.
                  > Example: an order is processed through the system
                  > and fails for some reason ( bad address, say ). A
                  > DB user fixes the address and queues up the order
                  > for reprocessing. If persistence has changed by the
                  > db user before the Order EJB passivates,
                  > reprocessing uses the cached EJB which reflects
                  > invalid data. The order fails again because the
                  > fixed address has not been read from persistence.
                  > Actually, once a business method is invoked on the
                  > e Order, the bad address is re-persisted and the db
                  > user's work is undone. Funny eh?

                  Well ejbStore is called so that is normal ;-)

                  > In short, I need to be very aware of exactly how
                  > ow long to keep EJBs around, and passivate them asap
                  > in order to minimize cases like this.

                  Passivate the bean will force a ejbLoad and db read again so imho that is not a solution.
                  Are you sure quick Passivation/ option A is quicker than no Passivation / Option B/C ?
                  Anyway these two solutions will gives you as many db hits/transaction.

                  > JBoss / synchronization via standard methods can
                  > an work, we just need to work on timing of our office
                  > processes.
                  > It'd be nice though if there were a way for an EJB
                  > JB to request the container to load it again.
                  > Interesting side note: EJB Spec [17.3.1]. If you
                  > ou write a method that throws a non-app exception,
                  > the container will discard the instance of the EJB
                  > that threw the exception. Catch it, of course. Then
                  > you can invoke the home interface's finder to load
                  > the same ejb, and you're pretty much guaranteed to
                  > get a fresh copy from persistence. Not advisable,
                  > but it'll be interesting to see if it works.

                  hehe, interesting...

                  • 6. Re: Force JBoss to synchronize entity.
                    larry054

                    Woodspeaker,

                    I had a similar problem once. I had a session bean that accessed hundreds of beans in a loop, similar to your order scenario. Each bean had a required CMT, so each iteration caused a new transaction. A non-EJB client could modify the data, so I had to use commit option B. I minimized the performance hit by programming the session bean to start a transaction. This meant the whole loop was processed as a single transaction, requiring only one synchronization.

                    I hope I explained this well. Does this help?

                    Larry

                    • 7. Re: Force JBoss to synchronize entity.
                      cknoll

                      I think it's one of the 'strict' aspects of J2EE programming, that only the persistance manager (ie. the container) should be messing with the datastore...why not just throw a simple UI together that allows the DBA guy to make the change? I know that means that the almighty DBA can't make raw data chanages, but we all have our crosses to bear :)

                      -Chris