jakarta-jcs-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Hanson Char <HC...@realm.com>
Subject RE: Why a cached object must be Serializable
Date Fri, 23 May 2003 13:02:26 GMT
What you describe is how to get around the problem, and of course there are
many ways one can achieve that.

But the bottom line is items cached in JCS are NOT thread safe.

A cached item retrieved from JCS can now be simultaneously modified by a
hundred threads, and the user of JCS must provide layers of code to
safeguard this concurrency chaos.


-----Original Message-----
From: Les Hazlewood [mailto:lhazlewood@transdynatlanta.com]
Sent: Friday, May 23, 2003 7:47 AM
To: 'Turbine JCS Users List'
Subject: RE: Why a cached object must be Serializable

> Therefore, an item put into the cache must be by value, and an item
> retrieved from the cache must also be by value.  In order to 
> achieve this, a
> cache item must be deeply cloned into copies.  The best way 
> to do so is by
> serializing and deserializing.


This is unnecessary behavior to be enforced.  Not everyone will want or need
such functionality.

Due to the performance/memory overhead of cloning everything, its not
advisable to do so automatically without the user being able to tell JCS.
That is, JCS should not force this behavior.

Perhaps, it would be better to have a switch in the .ccf file that allowed
this behavior.  Something that "turned on" caching objects by value rather
than by reference.  That will be up to the JCS developers.

At least for now, its better for JCS to cater to any possible use, rather
than enforce something many may find restrictive.

Using proper design patterns, you can easily complement JCS to provide the
functionality you describe.

For example, in my company, we use the DAO (Data Access Object) design
pattern to proxy access to the cache, and the VO (Value Object) design
pattern to transfer information to/from the cache.

The DAO has an internal, private static reference to the cache.  Any actions
done to an object in the cache is done via the DAO.  That is, no "user" of
the DAO ever gets a reference to any objects inside the DAO's JCS cache.
Instead, Value Objects containing the information we care about (to and
from) are used for transfer of information.

For example, lets say we're working on some product-driven system (e.g.
amazon.com or any other ecommerce site).  Caching a Product object would be
a good idea since the product information rarely changes.  But if this
Product needed to be updated, naturally, it would be a bad idea to just
update it immediately, without regard to other threads that might be
accessing it.

The dao does the "work" involved on the objects in the cache:

public ProductInfo getProductInfo(String productId);

This method returns a "clone" of the product's information as a ProductInfo
object (the Value Object)...its nothing but a JavaBean with getters and
setters to hold information.  It contains no logic.

Or the dao could have:

public void setProductName(String productId, String newName) 
    throws ProductUnavailableException;

This method would naturally set the name on the actual Product object inside
the DAO's JCS cache.

For example:

//in class attributes:
private static JCS productCache = JCS.getInstance("productCache");

public void setProductName(String productId, String newName) ...
    productCache = JCS.getInstance("productCache");

    Product aProduct = productCache.get(productId);

    if (aProduct == null)
        throw new ProductUnavailableException("not in cache");

    synchronized (aProduct)

Using synchronization and proper design patterns you can easily achieve what
you're looking for without worrying about threading blunders.

The above technique (DAO/VO) should absolutely be used in a J2EE environment
due to J2EE Container managed threads accessing the DAO (e.g. through a
Stateless Session Bean, SLSB).  The J2EE developer has no prior knowledge
when the container might enable a SLSB and access the underlying DAO, so the
synchronization code is necessary.  Value Objects are also a wise choice for
the J2EE developer due to RMI's performance when transferring many
fine-grained objects (String, int, etc) over a network connection.  The VO
must be serializable, and offers the best RMI performance when remotely
transferring a single large-grained object.

I hope this helps in sidestepping your problems with using JCS.  It works
great for us.

Les Hazlewood

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message