The performance of this may not work for your specific situation, but
my java web application allows for the possibility that some external
process may update the database like this:

I created a table: LAST_EXTERNAL_UPDATE with two fields:

ID
LAST_CHANGED

Any external process changes the LAST_CHANGED timestamp field whenever
something updates.

I created an alternative class to
org.apache.cayenne.conf.BasicServletConfiguration and changed
"getDataContext()" to check for external updates before returning the
dataContext.


        try
        {
            checkForExternalUpdates(dataContext, session);
        }
        catch (CayenneRuntimeException cayenneRuntimeException)
        {
            // If it failed, it probably failed during the database
read, so ignore
            // REPORT ERROR code here
        }


    public static void checkForExternalUpdates(DataContext
dataContext, String identityString, HttpSession session)
    {
        List lastExternalUpdateList = // FETCH YOUR
LAST_EXTERNAL_UPDATE RECORD CODE HERE;

        boolean willInvalidate = false;

        if (1 != lastExternalUpdateList.size())
        {
            // database error -- zero or multiple LastExternalUpdate
objects found
            // REPORT DATABASE ERROR CODE HERE
        }

        LastExternalUpdate latestExternalUpdateObject =
(LastExternalUpdate)lastExternalUpdateList.get(0);

        if (null == latestExternalUpdateObject)
        {
            willInvalidate = false;
        }
        else
        {
            final Date lastSessionExternalUpdateDate =
(Date)session.getAttribute("lastSessionExternalUpdateDate");

            Date latestChangedDate =
latestExternalUpdateObject.getLastChanged();
            if (null == latestChangedDate)
            {
                willInvalidate = false;
            }
            else if (null == lastSessionExternalUpdateDate)
            {
                willInvalidate = true;
            }
            else
            {
                if (lastSessionExternalUpdateDate.before(latestChangedDate))
                {
                    willInvalidate = true;
                }
                else
                {
                    willInvalidate = false;
                }
            }

            session.setAttribute("lastSessionExternalUpdateDate",
latestChangedDate);
        }

        if (willInvalidate)
        {
            
dataContext.invalidateObjects(dataContext.getObjectStore().getObjects());
        }
    }

Instead of a timer, this method checks every time you request the
session datacontext.   And it also invalidates everything if something
changed.  You can probably be far more selective than that.

On 5/5/08, Andrus Adamchik <[EMAIL PROTECTED]> wrote:
> for java-to-java invalidation I successfully used OSCache with JGroups. For
> non-java apps that change the data there are a few options:
>
>  1. A private URL in a webapp that a script can access that would cause
> cache invalidation
>  2. A timer local to the app that checks a special table in DB that is
> populated by the script on data changes.
>  3. A timer running in a remote Java app that checks a DB table, and then
> notifies another app with JGroups.
>  4. etc.
>
>  Andrus
>
>
>
>  On May 5, 2008, at 11:21 AM, Andreas Pardeike wrote:
>
>
> > Hi,
> >
> > I have an web application that serves html pages from a databases.
> > That database is manipulated from a perl program that runs from
> > within a proftpd ftp server. As a result, users can upload their
> > html pages via ftp and the web application displays them.
> >
> > I want to cache the page queries in the web application but have
> > not found a good way to invalidate a certain page in the cache once
> > a user uploads a modified version of it.
> >
> > I use:
> >
> > - Tomcat on Linux
> > - Tapestry 5
> > - Cayenne 3
> > - Mysql 5
> > - Custom mod_exec perl script in proftpd
> >
> > What is the best approach here?
> >
> > /Andreas Pardeike
> >
> >
>
>

Reply via email to