You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Ravi P Palacherla <ra...@oracle.com> on 2011/11/10 02:00:14 UTC

L1 and L2cache.

Hi,

I have a question about L1 cache refresh.

Lets say I have two Entity Managers in my application.

I have a simple JPAEntity entity that has id and name values.

Sequence of steps in the app:
--------------------------------
EntityManager EM1 does a query for JPAEntity with id=1.
EntityManager EM2 does a query for same JPAEntity with id=1.
EM1 updates name from "old" to "new"
Now when EM2 does the query again with id=1, it is showing the value of name
as "old" but not "new"

I disabled DataCache and QueryCache which means that EM2's query goes to
database but it still is showing old values. Reason I think is because EM2's
cache (L1cache) is not updated with "new" value.

Is my understanding correct ?
If yes, then is there a way I can refresh EM2's cache other than using
evict() or refresh() call ?

Regards,
Ravi.

--
View this message in context: http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6980197.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: L1 and L2cache.

Posted by Kevin Sutter <kw...@gmail.com>.
Sure, it would be a great feature.  It's just not as easy as you would
think...  Especially if the changes to the database are done outside of the
control of JPA...  I'd be surprised if we didn't already have a JIRA
Feature open for this, but if you don't find one, then please do create
one.  Thanks.

On Mon, Nov 14, 2011 at 12:29 PM, Ravi Palacherla <
ravi.palacherla@oracle.com> wrote:

> Yes it may not be a bug, but will it not be nice to have a feature like
> this in openJPA ?
>
> Especially when a deleted entity ( deleted by other EntityManager) is
> being recognized by other entitymanagers ( even though this entity is in
> L1cache)
> Will it not be nice for updated entities ( updated by other EntityManager)
> to reflect the change in L1cache of other EMs , especially when user is
> choosing to go to the DB for queries( by disabling query cache) ?
>
> Regards,
> Ravi.
>
> On Nov 14, 2011, at 10:37 AM, Kevin Sutter wrote:
>
> > I don't consider it a bug.  That's the nature of optimistic locking.
> > Unless you clear or refresh the caches you are working with, there is the
> > risk of accessing stale data due to other transactional activity against
> > the database.
> >
> > Kevin
> >
> > On Mon, Nov 14, 2011 at 11:23 AM, Ravi Palacherla <
> > ravi.palacherla@oracle.com> wrote:
> >
> >> Hi Kevin,
> >>
> >> In my case the queries are going to the database as I disabled query
> cache.
> >> The problem is after the query is executed, it still returns the old
> >> values based on the values in L1cache.
> >> I dont think the IgnoreChanges value is going to effect the L1cache.
> >>
> >> For deleted rows I am not getting old values from L1cache but the
> problem
> >> is only for updated rows where the updated values are not reflected in
> the
> >> L1cache.
> >> So can this be considered a bug where when a query is executed against
> >> database it is supposed to change the L1cache values(in case of stale
> data
> >> in cache) ?
> >>
> >> Regards,
> >> Ravi.
> >>
> >> On Nov 14, 2011, at 9:36 AM, Kevin Sutter wrote:
> >>
> >>> Hi Ravi,
> >>> There are a couple of properties that sort of relate to what you are
> >>> requesting.  These are the IgnoreChanges and FlushBeforeQueries
> >> properties
> >>> as documented here:
> >>>
> >>
> http://openjpa.apache.org/builds/apache-openjpa-1.2.3-SNAPSHOT/docs/manual/manual.html#ref_guide_dbsetup_retain
> >>>
> >>> Although these properties pertain to your current transactional state
> (vs
> >>> other transactional state), they still may do the trick with forcing
> the
> >>> queries against the database instead of performing an in-memory query.
> >>> Specifically, you might want to try setting IgnoreChanges to true
> >> (default
> >>> is false).
> >>>
> >>> Other than that, I think you have to resort to the programmatic
> approach
> >> of
> >>> clearing or refreshing the state of the entities.
> >>>
> >>> Good luck,
> >>> Kevin
> >>>
> >>> On Mon, Nov 14, 2011 at 9:32 AM, Ravi P Palacherla <
> >>> ravi.palacherla@oracle.com> wrote:
> >>>
> >>>> EM2's persistence context is not closed and it is executing the
> queries
> >>>> outside transaction.
> >>>>
> >>>> The entity still exists in L1 cache and hence the old values are
> shown.
> >> How
> >>>> to clear the L1cache ?
> >>>> I think there are ways like, entityManager.clear() or refresh() or
> >> evict()
> >>>> or using new entityManager.
> >>>> But all of these are programatic approaches where there is a chance
> that
> >>>> most of the times the data is not changed by EM1 but I still end up
> >>>> clearing
> >>>> EM2's cache.
> >>>>
> >>>> So is there a way I can tell openJPA , when a query is executed, to
> >> verify
> >>>> if the objects in L1cache are out of sync with L2cache (or when a
> query
> >>>> goes
> >>>> to datasource and L1cache values are different from the one's in
> >>>> datasource)
> >>>> and if they are different then update the L1cache with values of
> >> L2cache or
> >>>> datasource ?
> >>>>
> >>>> --
> >>>> View this message in context:
> >>>>
> >>
> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
> >>>> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> >>>>
> >>
> >>
>
>

Re: L1 and L2cache.

Posted by Ravi Palacherla <ra...@oracle.com>.
Yes it may not be a bug, but will it not be nice to have a feature like this in openJPA ?

Especially when a deleted entity ( deleted by other EntityManager) is being recognized by other entitymanagers ( even though this entity is in L1cache)
Will it not be nice for updated entities ( updated by other EntityManager) to reflect the change in L1cache of other EMs , especially when user is choosing to go to the DB for queries( by disabling query cache) ?

Regards,
Ravi.

On Nov 14, 2011, at 10:37 AM, Kevin Sutter wrote:

> I don't consider it a bug.  That's the nature of optimistic locking.
> Unless you clear or refresh the caches you are working with, there is the
> risk of accessing stale data due to other transactional activity against
> the database.
> 
> Kevin
> 
> On Mon, Nov 14, 2011 at 11:23 AM, Ravi Palacherla <
> ravi.palacherla@oracle.com> wrote:
> 
>> Hi Kevin,
>> 
>> In my case the queries are going to the database as I disabled query cache.
>> The problem is after the query is executed, it still returns the old
>> values based on the values in L1cache.
>> I dont think the IgnoreChanges value is going to effect the L1cache.
>> 
>> For deleted rows I am not getting old values from L1cache but the problem
>> is only for updated rows where the updated values are not reflected in the
>> L1cache.
>> So can this be considered a bug where when a query is executed against
>> database it is supposed to change the L1cache values(in case of stale data
>> in cache) ?
>> 
>> Regards,
>> Ravi.
>> 
>> On Nov 14, 2011, at 9:36 AM, Kevin Sutter wrote:
>> 
>>> Hi Ravi,
>>> There are a couple of properties that sort of relate to what you are
>>> requesting.  These are the IgnoreChanges and FlushBeforeQueries
>> properties
>>> as documented here:
>>> 
>> http://openjpa.apache.org/builds/apache-openjpa-1.2.3-SNAPSHOT/docs/manual/manual.html#ref_guide_dbsetup_retain
>>> 
>>> Although these properties pertain to your current transactional state (vs
>>> other transactional state), they still may do the trick with forcing the
>>> queries against the database instead of performing an in-memory query.
>>> Specifically, you might want to try setting IgnoreChanges to true
>> (default
>>> is false).
>>> 
>>> Other than that, I think you have to resort to the programmatic approach
>> of
>>> clearing or refreshing the state of the entities.
>>> 
>>> Good luck,
>>> Kevin
>>> 
>>> On Mon, Nov 14, 2011 at 9:32 AM, Ravi P Palacherla <
>>> ravi.palacherla@oracle.com> wrote:
>>> 
>>>> EM2's persistence context is not closed and it is executing the queries
>>>> outside transaction.
>>>> 
>>>> The entity still exists in L1 cache and hence the old values are shown.
>> How
>>>> to clear the L1cache ?
>>>> I think there are ways like, entityManager.clear() or refresh() or
>> evict()
>>>> or using new entityManager.
>>>> But all of these are programatic approaches where there is a chance that
>>>> most of the times the data is not changed by EM1 but I still end up
>>>> clearing
>>>> EM2's cache.
>>>> 
>>>> So is there a way I can tell openJPA , when a query is executed, to
>> verify
>>>> if the objects in L1cache are out of sync with L2cache (or when a query
>>>> goes
>>>> to datasource and L1cache values are different from the one's in
>>>> datasource)
>>>> and if they are different then update the L1cache with values of
>> L2cache or
>>>> datasource ?
>>>> 
>>>> --
>>>> View this message in context:
>>>> 
>> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
>>>> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>>>> 
>> 
>> 


Re: L1 and L2cache.

Posted by Kevin Sutter <kw...@gmail.com>.
I don't consider it a bug.  That's the nature of optimistic locking.
Unless you clear or refresh the caches you are working with, there is the
risk of accessing stale data due to other transactional activity against
the database.

Kevin

On Mon, Nov 14, 2011 at 11:23 AM, Ravi Palacherla <
ravi.palacherla@oracle.com> wrote:

> Hi Kevin,
>
> In my case the queries are going to the database as I disabled query cache.
> The problem is after the query is executed, it still returns the old
> values based on the values in L1cache.
> I dont think the IgnoreChanges value is going to effect the L1cache.
>
> For deleted rows I am not getting old values from L1cache but the problem
> is only for updated rows where the updated values are not reflected in the
> L1cache.
> So can this be considered a bug where when a query is executed against
> database it is supposed to change the L1cache values(in case of stale data
> in cache) ?
>
> Regards,
> Ravi.
>
> On Nov 14, 2011, at 9:36 AM, Kevin Sutter wrote:
>
> > Hi Ravi,
> > There are a couple of properties that sort of relate to what you are
> > requesting.  These are the IgnoreChanges and FlushBeforeQueries
> properties
> > as documented here:
> >
> http://openjpa.apache.org/builds/apache-openjpa-1.2.3-SNAPSHOT/docs/manual/manual.html#ref_guide_dbsetup_retain
> >
> > Although these properties pertain to your current transactional state (vs
> > other transactional state), they still may do the trick with forcing the
> > queries against the database instead of performing an in-memory query.
> > Specifically, you might want to try setting IgnoreChanges to true
> (default
> > is false).
> >
> > Other than that, I think you have to resort to the programmatic approach
> of
> > clearing or refreshing the state of the entities.
> >
> > Good luck,
> > Kevin
> >
> > On Mon, Nov 14, 2011 at 9:32 AM, Ravi P Palacherla <
> > ravi.palacherla@oracle.com> wrote:
> >
> >> EM2's persistence context is not closed and it is executing the queries
> >> outside transaction.
> >>
> >> The entity still exists in L1 cache and hence the old values are shown.
> How
> >> to clear the L1cache ?
> >> I think there are ways like, entityManager.clear() or refresh() or
> evict()
> >> or using new entityManager.
> >> But all of these are programatic approaches where there is a chance that
> >> most of the times the data is not changed by EM1 but I still end up
> >> clearing
> >> EM2's cache.
> >>
> >> So is there a way I can tell openJPA , when a query is executed, to
> verify
> >> if the objects in L1cache are out of sync with L2cache (or when a query
> >> goes
> >> to datasource and L1cache values are different from the one's in
> >> datasource)
> >> and if they are different then update the L1cache with values of
> L2cache or
> >> datasource ?
> >>
> >> --
> >> View this message in context:
> >>
> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
> >> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> >>
>
>

Re: L1 and L2cache.

Posted by Ravi Palacherla <ra...@oracle.com>.
Hi Kevin,

In my case the queries are going to the database as I disabled query cache.
The problem is after the query is executed, it still returns the old values based on the values in L1cache.
I dont think the IgnoreChanges value is going to effect the L1cache.

For deleted rows I am not getting old values from L1cache but the problem is only for updated rows where the updated values are not reflected in the L1cache.
So can this be considered a bug where when a query is executed against database it is supposed to change the L1cache values(in case of stale data in cache) ?

Regards,
Ravi.

On Nov 14, 2011, at 9:36 AM, Kevin Sutter wrote:

> Hi Ravi,
> There are a couple of properties that sort of relate to what you are
> requesting.  These are the IgnoreChanges and FlushBeforeQueries properties
> as documented here:
> http://openjpa.apache.org/builds/apache-openjpa-1.2.3-SNAPSHOT/docs/manual/manual.html#ref_guide_dbsetup_retain
> 
> Although these properties pertain to your current transactional state (vs
> other transactional state), they still may do the trick with forcing the
> queries against the database instead of performing an in-memory query.
> Specifically, you might want to try setting IgnoreChanges to true (default
> is false).
> 
> Other than that, I think you have to resort to the programmatic approach of
> clearing or refreshing the state of the entities.
> 
> Good luck,
> Kevin
> 
> On Mon, Nov 14, 2011 at 9:32 AM, Ravi P Palacherla <
> ravi.palacherla@oracle.com> wrote:
> 
>> EM2's persistence context is not closed and it is executing the queries
>> outside transaction.
>> 
>> The entity still exists in L1 cache and hence the old values are shown. How
>> to clear the L1cache ?
>> I think there are ways like, entityManager.clear() or refresh() or evict()
>> or using new entityManager.
>> But all of these are programatic approaches where there is a chance that
>> most of the times the data is not changed by EM1 but I still end up
>> clearing
>> EM2's cache.
>> 
>> So is there a way I can tell openJPA , when a query is executed, to verify
>> if the objects in L1cache are out of sync with L2cache (or when a query
>> goes
>> to datasource and L1cache values are different from the one's in
>> datasource)
>> and if they are different then update the L1cache with values of L2cache or
>> datasource ?
>> 
>> --
>> View this message in context:
>> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
>> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>> 


Re: L1 and L2cache.

Posted by Kevin Sutter <kw...@gmail.com>.
Hi Ravi,
There are a couple of properties that sort of relate to what you are
requesting.  These are the IgnoreChanges and FlushBeforeQueries properties
as documented here:
http://openjpa.apache.org/builds/apache-openjpa-1.2.3-SNAPSHOT/docs/manual/manual.html#ref_guide_dbsetup_retain

Although these properties pertain to your current transactional state (vs
other transactional state), they still may do the trick with forcing the
queries against the database instead of performing an in-memory query.
Specifically, you might want to try setting IgnoreChanges to true (default
is false).

Other than that, I think you have to resort to the programmatic approach of
clearing or refreshing the state of the entities.

Good luck,
Kevin

On Mon, Nov 14, 2011 at 9:32 AM, Ravi P Palacherla <
ravi.palacherla@oracle.com> wrote:

> EM2's persistence context is not closed and it is executing the queries
> outside transaction.
>
> The entity still exists in L1 cache and hence the old values are shown. How
> to clear the L1cache ?
> I think there are ways like, entityManager.clear() or refresh() or evict()
> or using new entityManager.
> But all of these are programatic approaches where there is a chance that
> most of the times the data is not changed by EM1 but I still end up
> clearing
> EM2's cache.
>
> So is there a way I can tell openJPA , when a query is executed, to verify
> if the objects in L1cache are out of sync with L2cache (or when a query
> goes
> to datasource and L1cache values are different from the one's in
> datasource)
> and if they are different then update the L1cache with values of L2cache or
> datasource ?
>
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: L1 and L2cache.

Posted by Ravi P Palacherla <ra...@oracle.com>.
EM2's persistence context is not closed and it is executing the queries
outside transaction.

The entity still exists in L1 cache and hence the old values are shown. How
to clear the L1cache ?
I think there are ways like, entityManager.clear() or refresh() or evict()
or using new entityManager.
But all of these are programatic approaches where there is a chance that
most of the times the data is not changed by EM1 but I still end up clearing
EM2's cache.

So is there a way I can tell openJPA , when a query is executed, to verify
if the objects in L1cache are out of sync with L2cache (or when a query goes
to datasource and L1cache values are different from the one's in datasource)
and if they are different then update the L1cache with values of L2cache or
datasource ?

--
View this message in context: http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6992870.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: L1 and L2cache.

Posted by Kevin Sutter <kw...@gmail.com>.
Hi Ravi,
You don't mention anything about transactions or persistence contexts in
your description, so I'm not sure when things are getting cleared out
naturally.

The normal path of finding an entity is through the Persistence Context (L1
cache), then the L2 cache (if configured), then the database.  The idea
being is that even if you get an "old" copy of the data at least it will be
discovered if you attempt to make changes to it (optimistic locking).  If
you want to force the app to get an updated copy, then you have to clear
out the respective cache of the given entity.

You mentioned that turning off the L2 cache should be forcing OpenJPA to
the database.  Not if you still have that Entity instance in your L1 cache.

I would try your scenario with turning on Trace so that you can see where
the "old" data is coming from.  My guess is this entity still exists in
your L1 cache.  You can clear that by either closing or clearing the EM.
Depending on the version of OpenJPA you are using, you could also detach
the specific entity from your persistence context.

Hope this helps,
Kevin

On Wed, Nov 9, 2011 at 7:00 PM, Ravi P Palacherla <
ravi.palacherla@oracle.com> wrote:

> Hi,
>
> I have a question about L1 cache refresh.
>
> Lets say I have two Entity Managers in my application.
>
> I have a simple JPAEntity entity that has id and name values.
>
> Sequence of steps in the app:
> --------------------------------
> EntityManager EM1 does a query for JPAEntity with id=1.
> EntityManager EM2 does a query for same JPAEntity with id=1.
> EM1 updates name from "old" to "new"
> Now when EM2 does the query again with id=1, it is showing the value of
> name
> as "old" but not "new"
>
> I disabled DataCache and QueryCache which means that EM2's query goes to
> database but it still is showing old values. Reason I think is because
> EM2's
> cache (L1cache) is not updated with "new" value.
>
> Is my understanding correct ?
> If yes, then is there a way I can refresh EM2's cache other than using
> evict() or refresh() call ?
>
> Regards,
> Ravi.
>
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/L1-and-L2cache-tp6980197p6980197.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>