Re: Caching/Concurrency Questions

From: PaulC.177094..loglines.com
Date: Wed Jun 09 2004 - 11:34:17 EDT

  • Next message: Andrus Adamchik: "Re: Caching/Concurrency Questions"

    > Hi Paul,
    >
    > Good question, I should've mentioned that.
    >
    > Two DataObjects residing in peer DataContexts have no "hard" link with?
    > each other. What makes them "related" is their ObjectIds.
    >
    > Now, when an object is updated and then committed in one DataContext,
    > what happens to the peers? Peer synchronization is done via events.
    > Default behavior of the peer DataContext [see
    > ObjectStore.snapshotsChanged(..) method for details] is to invalidate
    > all COMMITTED objects, and merge changes to the MODIFIED and DELETED
    > objects. But if the same property is already modified in the peer
    > object, merge process will leave it alone.
    >
    > If you want fine grained control over merging behavior, implement a
    > DataContextDelegate:
    > http://objectstyle.org/cayenne/userguide/datactxt/data-context-
    > delegate.html
    >
    > Andrus
    >

    Andrus,

    Thanks again for the explanation - this is what I would have expected but
    for some reason in the test code (below) I dont see the peer merging. I may
    have some configuration options wrong or be doing something odd but do have
    shared cache enabled for the domain - any further insight would be
    appreciated !

    public class TestConcurrent {

        public static String printState(String title, Artist r1, Artist r2) {
            return title + " - [dc1] r1.name='" + r1.getArtistName() + "' "
                         + "(State=" + r1.getPersistenceState() + ") / "
                         + " [dc2] r2.name='" + r2.getArtistName() + "' "
                         + "(State=" + r2.getPersistenceState() + ")";
        }

        public static void main(String[] args) {

            DataContext dc1 = DataContext.createDataContext();
            DataContext dc2 = DataContext.createDataContext();

            LogDelegate ld1 = new LogDelegate();
            ld1.setPrefix(">>> (DC1) Delegate");
            dc1.setDelegate(ld1);

            LogDelegate ld2 = new LogDelegate();
            ld2.setPrefix(">>> (DC2) Delegate");
            dc2.setDelegate(ld2);

            // Create Test Record
            Artist a1 = (Artist) dc1.createAndRegisterNewObject(Artist.class);
            a1.setArtistName("Original");
            dc1.commitChanges();

            Expression qual = Expression.fromString("artistName = 'Original'");
            SelectQuery query = new SelectQuery(Artist.class,qual);

            List result1 = dc1.performQuery(query);
            List result2 = dc2.performQuery(query);

            // Skip error check for the moment
            Artist r1 = (Artist) result1.get(0);
            Artist r2 = (Artist) result2.get(0);
                
            System.out.println(printState("--- Initial Load ",r1,r2));

            r1.setArtistName("Changed in DC1");
            System.out.println(printState("--- Update in DC1",r1,r2));

            dc1.commitChanges();
            System.out.println(printState("--- Commit in DC1",r1,r2));
        }
    }

    (LogDelegate is DataContextDelegate which just logs the delegate methods)

    When I run this I get the following:

    >>> (DC1) Delegate:willPerformSelect - org.objectstyle.cayenne.query.SelectQuer..d4c49
    >>> (DC2) Delegate:willPerformSelect - org.objectstyle.cayenne.query.SelectQuer..d4c49
    --- Initial Load - [dc1] r1.name='Original' (State=3) / [dc2] r2.name='Original' (State=3)
    --- Update in DC1 - [dc1] r1.name='Changed in DC1' (State=4) / [dc2] r2.name='Original' (State=3)
    --- Commit in DC1 - [dc1] r1.name='Changed in DC1' (State=3) / [dc2] r2.name='Original' (State=3)

    It doesnt look like the delegate mergeChanges methods are being called
    and the object in dc2 is stale.

    Paul



    This archive was generated by hypermail 2.0.0 : Wed Jun 09 2004 - 11:34:21 EDT