These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: 'Separate' ehcache in a user thread
PostPosted: Wed Feb 06, 2008 3:40 am 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

I have a Seam+Hibernate app and I have setup a 2nd level cache for, using ehcache (1.2.3), for some of my entities. And it works fine, if I access the site using a browser.

However, I also need to access the Seam components from a daemon thread; but the thread and the "browser threads" seem to have separate caches - if I modify something from the browser (in the DB), the change is not visible in the daemon thread, because it uses old cached values. The values displayed in the browser (which are also read from the cache) are correct, so on the "browser threads" side, the cache is invalidated as expected.

Here's what I do in the daemon thread:
Code:
            boolean createContexts = !Contexts.isEventContextActive() && !Contexts.isApplicationContextActive();
            if (createContexts) {
                Lifecycle.beginCall();
            }
           
            try {
                UserTransaction tx = null;
                boolean txStarted = false;
                try {
                    tx = (UserTransaction) Component.getInstance("org.jboss.seam.transaction.transaction");
                    if (tx.getStatus() != Status.STATUS_ACTIVE) {
                        txStarted = true;
                        tx.begin();
                    }

                    ((EntityManager) Component.getInstance("entityManager")).joinTransaction();
                    ((UpdateHandler) Component.getInstance("updateHandler")).update();

                    if (txStarted) {
                        tx.commit();
                    }
                }  catch (Exception e) {
                    try {
                        if (txStarted) {
                            tx.rollback();
                        }
                    } catch (SystemException e1) {
                        Logging.getLog(UpdateManager.class).error("Exception when rolling back the transaction", e1);
                    }

                    e.printStackTrace();
                }
            } finally {
                if (createContexts) {
                    Lifecycle.endCall();
                }
            }


So basically I:
* setup Seam contexts: Lifecycle.beginCall()
* start a transcation, if necessary
* invoke a method of a component (UpdateHandler.update())
* commit the transaction
* Lifecycle.endCall()

Am I missing something? Of course, I'd like to have only one cache :).

--
Regards,
Adam Warski


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 06, 2008 8:25 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Hi, I don't know if this will help or not but I also spawn threads from a web application (using Tomcat for dev and Weblogic in production/testing). I've not had any problems with the second level cache from within spawned threads or the container's threadpool.

Couple of questions...

What CacheConcurrencyStrategy do you use?

How often are you spawning threads, and how long will they typically run for?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 06, 2008 1:27 pm 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

I use the "read_write" concurrency strategy.

I have only one thread, but it performs operations every 10 seconds (using a ScheduledExecutorService); the changes are not visible not only just after being made, but also after some time (10, 20, 30 seconds, etc).

Oh, maybe it's not clear from the code, but a new transaction is started and then commited on every thread invocation.

--
Adam


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 06, 2008 3:34 pm 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
I'm not an expert I'm afraid but I'm wondering if you are keeping a hibernate session open permanently in your thread? If so you may need to force a flush() every so often.

Other than that this is outside my experiance, sorry.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 06, 2008 4:25 pm 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

no, I don't use hibernate sessions directly at all, as I'm using Seam and an injected EntityManager (which's lifecycle isn't handeled by me)

Thanks anyway :)
Adam


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 07, 2008 5:33 am 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

Also, this is not eh-cache specific; when I turned it off and left the default 2nd level cache provider (org.hibernate.cache.HashtableCacheProvider), the issue is still there.

--
Adam


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 07, 2008 12:16 pm 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

here's a little more on the situation. This weird behaviour happens both with the Ehcache and Hashtable cache. I use hibernate as it is in packaged with Seam 2.0.1.

As I wrote, I have a background daemon thread, which executes a query every 30 seconds, and a regular web interface (in Seam). Both use the same beans to retrieve the data.

There is in fact one specific query which returns wrong results - others work fine:
- I execute a "select * from Entity1", with query caching on
- then, for each instance of Entity1, I do: entity1.getCollectionOfEntity2().

Now, the problem seems to be that ids of Entity2 in the collections of Entity1-s are wrongly cached - if I add a new Entity1, or modify an Entity2, the changes are seen both by the daemon thread and the "web" threads.

However, if I add/remove a new Entity2 to a collection in Entity1 (via the web interface - using a "web thread"), the change is visible *only* to the "web threads" - it isn't visible to the daemon thread (both use the same beans to read the data).

So on one hand the cache seems to have correct results - I see the changes in the browser, but on the other hand it has incorrect results - the daemon thread sees something different.

Anybody got any ideas why this happens?

Regards,
Adam Warski


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 07, 2008 12:21 pm 
Newbie

Joined: Mon Nov 06, 2006 6:19 pm
Posts: 16
Hello,

here's a little more on the situation. This weird behaviour happens both with the Ehcache and Hashtable cache. I use hibernate as it is in packaged with Seam 2.0.1.

As I wrote, I have a background daemon thread, which executes a query every 30 seconds, and a regular web interface (in Seam). Both use the same beans to retrieve the data.

There is in fact one specific query which returns wrong results - others work fine:
- I execute a "select * from Entity1", with query caching on
- then, for each instance of Entity1, I do: entity1.getCollectionOfEntity2().

Now, the problem seems to be that ids of Entity2 in the collections of Entity1-s are wrongly cached - if I add a new Entity1, or modify an Entity2, the changes are seen both by the daemon thread and the "web" threads.

However, if I add/remove a new Entity2 to a collection in Entity1 (via the web interface - using a "web thread"), the change is visible *only* to the "web threads" - it isn't visible to the daemon thread (both use the same beans to read the data).

So on one hand the cache seems to have correct results - I see the changes in the browser, but on the other hand it has incorrect results - the daemon thread sees something different.

Anybody got any ideas why this happens?

Regards,
Adam Warski


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.