8 Replies Latest reply on May 16, 2006 1:42 PM by brian.stansberry

    two Processes getting the 'same' object

      Hi all there,

      I'm trying to better understand how TreeCache works interally and so I've two questions.

      Following scenario:
      - using GenericTransactionManagerLookup
      - IsolationLevel is REPEATABLE_READ
      - CacheMode is LOCAL.
      - Two Processes A and B.

      1. Process A starts a new Transaction.
      2. Process A calls get(Object x)?.
      3. Process A modifies Object x (e.g x.setAttribut(?abc?)).
      4. Process B calls get(Object x).
      5. Process A commits the Transaction.

      Q.1.: I?m right Process B get?s an unmodified Object x?
      Q.2.: So internally the get() method clones the Object x?

      Thanks for any answer
      Jochen

        • 1. Re: two Processes getting the 'same' object
          brian.stansberry

          No, process B would see the modified data. TreeCache's locking semantics control access to nodes in the cache, but once you have retrieved the data from a node it is up to you to control concurrent use of it.

          • 2. Re: two Processes getting the 'same' object
            bruce76

            Brian,

            I'm somewhat surprised by your answer. What's the purpose of transactions if changes are automatically reflected?

            -Bruce

            • 3. Re: two Processes getting the 'same' object
              brian.stansberry

              If you need the cache to enforce fine-grained control over the internals of mutable cached objects, you need to use PojoCache (fka TreeCacheAop).

              As ajoe stated, otherwise enforcing such control would mean the cache would have to clone all objects before returning them. But who knows if cached objects are Clonable? And how do they implement cloning -- is it a shallow copy or a deep one?

              What seems to be missing here is some kind of analogue to SELECT FOR UPDATE -- i.e. a getForUpdate() for Step 2 of the sequence which would then acquire a write lock on the node instead of a read lock. The presence of the WL would then prevent Process B reading the node until the tx commits.

              • 4. Re: two Processes getting the 'same' object
                bruce76

                So then I guess I have to ask the stupid question...

                What if A rollsback the transaction instead of committing it in step 5? Will B have the modified (incorrect) data, or the unmodified (correct) data?

                Thanks,

                Bruce

                • 5. Re: two Processes getting the 'same' object

                  Hi all

                  only to clarify my understanding, if I change the CacheMode to REPL_SYNC and the Process B in another JVM than, the Process B doesn't 'see' the modified Object x, instead it would get an unmodified Object x. After Process A has committed, also Process B would 'see' the modified Object x.
                  Is this correct?

                  Thanks a lot
                  Jochen

                  PS: It looks like I could/should write the next wiki page ;-)

                  PPS: @bruce76: I don't think that is a stupid question, because as far as I know, there is only little documentation about this topic and you have to guess how JBoss Cache works in this cases.

                  • 6. Re: two Processes getting the 'same' object
                    brian.stansberry

                    Bruce,

                    The key thing is there is only one copy of the object. If one thread makes a change to the object, and code executing in another thread has a reference to that object, the 2nd thread immediately sees changes made by the 1st.

                    An ordinary object is not a transactional resource; if changes are made to it during a tx, and the tx rolls back, the changes will only be reversed if the application that made them detects the rollback and reverses the changes.

                    Any other thread with a reference to the same object would see any changes immediately.

                    • 7. Re: two Processes getting the 'same' object
                      brian.stansberry

                      Jochen,

                      Yes, with REPL_SYNC or REPL_ASYNC, changes are replicated around the cluster as part of transaction commit, so Process B would not see any changes until Process A's tx commits.

                      Actually, with the sequence you initially wrote, the changes would not be replicated at all. TreeCache does not know Process A changed the object; to get replication to occur you would need to do a put to the cache:

                      1. Process A starts a new Transaction.
                      2. Process A calls get(Fqn for x, key for Object x)?.
                      3. Process A modifies Object x (e.g x.setAttribut(?abc?)).
                      3.5 Process A calls put(Fqn for x, key for x, x);
                      4. Process B calls get(Fqn for x, key for Object x).
                      5. Process A commits the Transaction.

                      Note that step 3.5 aquires a write lock. In LOCAL mode, this WL would block Process B from doing a read until Process A commits. But, there is a race condition here -- what if Process B does its read in between 3 and 3.5? That race is the reason I mentioned the need for a getForUpdate() concept.

                      With replication, the put() in 3.5. would be replicated around the cache as part of committing the tx in step 5. If Process B did its read before the replication it would see the old state. If after the replication, it sees the new state. If it tries to read in the middle of the replication, it blocks briefly as the replicated put has a WL on the node. Then its read goes through and it sees the new state.

                      • 8. Re: two Processes getting the 'same' object
                        brian.stansberry

                        Bruce,

                        A cool side effect of instrumenting your classes for use with TreeCacheAop is that once an object is placed in the cache, changes made to it are transparently transactional. So, if changes are made to the object in a tx, and then the tx rolls back, the changes are reversed by TreeCacheAop.

                        This can only happen with instrumented classes and TreeCacheAop; without the instrumentation the cache has no way to know an object stored within it has been modified.