Does flush() sync with the db or the L2 cache? [message #667743] |
Sun, 01 May 2011 23:59 |
Brendan Healey Messages: 12 Registered: May 2010 |
Junior Member |
|
|
I've hit a problem running some code in an EJB timer routine that is, I strongly suspect,
demonstrating the limitations of my understanding of the JPA/EclipseLink caching
mechanism. I am using Glassfish 3.1, Eclipse Persistence Services - 2.2.0.v20110202-r8913
and MySQL 5.1.50, container managed transaction scoped entity manager.
My timer routine does this:
- named query on a table to get list of unprocessed events
- for each unprocessed event returned by the query:
- process the event
- set the processed state flag to processed
- flush()
- end
Because the timer process is running in a transaction I simply call the setter to change the
processed flag, without calling EntityManager.merge(), it's a managed entity after all. I would
expect the change to commit following return from the timer routine, and implicitly, the end of
the transaction.
Where I'm querying and modifying the 'processed' flag from within the persistence context all is ok,
but for testing purposes I was changing the processed flag in the database externally from processed
to unprocessed. I understand a bit about the L2 cache, but I thought an explicit flush(), in my test
setup would write to the database, but this doesn't happen.
Using the default flush mode AUTO the named query always returns the results from the database,
despite being modified outside the application. The problem seems to be that having made the
modification from outside the application, the modification of the process state flag never gets beyond
the L2 cache, unless I specifically evict() it from the cache or completely disable shared-cache-mode.
It does not get written to the database otherwise, but if I've not modified it 'externally', it does.
A flush() doesn't do it, nor does setting a DoNotCache query hint. If anyone can explain what I'm
seeing it would be a great help.
Thanks.
[Updated on: Mon, 02 May 2011 00:02] Report message to a moderator
|
|
|
Re: Does flush() sync with the db or the L2 cache? [message #667918 is a reply to message #667743] |
Mon, 02 May 2011 18:52 |
|
When you read an object into an EntityManager, it becomes part of the persistence context, and the same object will remain in the EntityManager until you either clear() it and get a new EntityManager. So if you update the database, the EntityManager will not see the change unless you call refresh() on the object, or clear() the EntityManager. This has nothing to do with the shared cache (L2) or the persistence context (L1).
If you also also using a shared cache, and updating the database directly, then your shared cache will be out of date. You need to refresh() the object, or mark it as invalid to be refreshed the next time it is queried.
Perhaps you can explain exactly what you are doing (with code).
James : Wiki : Book : Blog : Twitter
|
|
|
Re: Does flush() sync with the db or the L2 cache? [message #667950 is a reply to message #667918] |
Mon, 02 May 2011 23:38 |
Brendan Healey Messages: 12 Registered: May 2010 |
Junior Member |
|
|
Thanks for getting back to me, everything you said makes some sense. The key question
I'd like to get answered is 'why, when I update the database from outside the persistence
context, and a named query correctly detects the change, and I then from within the same
transaction make a modification to a managed entity (as retrieved by the query), does this
modification become neither visible to the same application running within the persistence
context or externally? i.e. the transaction is never flushed, even if I explicitly flush()?
In terms of what I'm actually doing, I'm calling a JAX-RS (Jersey 1.1) synchronous method
to execute an HTTP get request. I expect the latency of the request to be significant, and
hence have now re-worked the code to not use transaction scope and instead, on this
application scoped EJB, use BMT.
Thanks.
[Updated on: Mon, 02 May 2011 23:43] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.03254 seconds