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