Why not create a new DataContext when you need to do write operations?
On 3/25/08, Laurent Marchal <lmarcha..maeur.com> wrote:
> 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 - 20:36:36 EDT