Thread-safe Write DataContext

From: Laurent Marchal (lmarcha..maeur.com)
Date: Tue Mar 25 2008 - 14:30:55 EDT

  • Next message: Malcolm Edgar: "DataObjectUtils.objectForPK"

    Hi all !

    I spent some time searching documentation about the thread-safety status
    of DataContext, i found some answers on this mailing list but i would
    like to know some details :

    I have a big application (Eclipse RCP based) which monitors a database,
    so i have to poll the database each 10 seconds.
    To be simple i have a single DataContext in my App in :
    Session->getDataContext() and i created an API that look like

    public static List<User> getAll()
    {
        SelectQuery q = new SelectQuery(User.class);
       try {
                return (List<User>)Session.getDataContext().performQuery(q);
             } catch(CayenneRuntimeException e {
                //manage exception
            }
    }

    So everywhere the API use a single DataContext no bound to a thread.

    Naturally to be reactive the application fetch the data from the
    database in a background thread (actually there is one background thread
    for each view in the application), and what i've seen is that read
    operations are thread-safe within a DataContext so i don't care and all
    threads use the API and so the same DataContext.

    Here comes the complex part : I need this single DataContext to have a
    good cache in my app, and because the application is 90% visualization
    and only 10% modifications, so i just had to find a thread-safe
    workaround for writing data.
    I tried some solutions :
    - Bind a DC per thread is not a good solution because all my fetching is
    in background threads so the main Session DC (in the UI thread) is never
    updated.
    - I have tried to create a childDataContext bound to the current thread
    for writing, but i had some strange behaviors, and i don't know if the
    flushToParent() is thread safe ?

    So i would like to know if the new LifecycleListener can be used to
    "lock" the DataContext while writing, to have a single thread-safe R/W
    DataContext like :

    dataContext.getEntityResolver().getCallbackRegistry().addDefaultListener(new
    LifecycleListener(){

                    Lock lock = new ReentrantLock();

                    public void postPersist(Object entity) {
                        lock.unlock();
                    }
                    public void postRemove(Object entity) {
                        lock.unlock();
                    }
                    public void postUpdate(Object entity) {
                        lock.unlock();
                    }
                    public void prePersist(Object entity) {
                        lock.lock();
                    }
                    public void preRemove(Object entity) {
                        lock.lock();
                    }
                    public void preUpdate(Object entity) {
                        lock.lock();
                    }
    });

    Do you think it can be a good solution ?

    Thanks.

    Laurent Marchal.



    This archive was generated by hypermail 2.0.0 : Tue Mar 25 2008 - 14:31:36 EDT