[seam-commits] Seam SVN: r8740 - trunk/doc/Seam_Reference_Guide/en-US.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Tue Aug 19 18:09:38 EDT 2008
Author: pete.muir at jboss.org
Date: 2008-08-19 18:09:38 -0400 (Tue, 19 Aug 2008)
New Revision: 8740
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Cache.xml
Log:
WS
Modified: trunk/doc/Seam_Reference_Guide/en-US/Cache.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Cache.xml 2008-08-19 21:36:11 UTC (rev 8739)
+++ trunk/doc/Seam_Reference_Guide/en-US/Cache.xml 2008-08-19 22:09:38 UTC (rev 8740)
@@ -2,199 +2,194 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
<chapter id="cache">
- <title>Caching</title>
-
- <para>
- In almost all enterprise applications, the database is the primary
- bottleneck, and the least scalable tier of the runtime environment.
- People from a PHP/Ruby environment will try to tell you that so-called
- "shared nothing" architectures scale well. While that may be literally
- true, I don't know of many interesting multi-user applications which
- can be implemented with no sharing of resources between different
- nodes of the cluster. What these silly people are really thinking of
- is a "share nothing except for the database" architecture. Of course,
- sharing the database is the primary problem with scaling a multi-user
- application—so the claim that this architecture is highly scalable
- is absurd, and tells you a lot about the kind of applications that these
- folks spend most of their time working on.
- </para>
-
- <para>
- Almost anything we can possibly do to share the database <emphasis>less
- often</emphasis> is worth doing.
- </para>
-
- <para>
- This calls for a cache. Well, not just one cache. A well designed Seam
- application will feature a rich, multi-layered caching strategy that
- impacts every layer of the application:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- The database, of course, has its own cache. This is
- super-important, but can't scale like a cache in the
- application tier.
- </para>
- </listitem>
- <listitem>
- <para>
- Your ORM solution (Hibernate, or some other JPA implementation)
- has a second-level cache of data from the database. This is
- a very powerful capability, but is often misused. In a clustered
- environment, keeping the data in the cache transactionally
- consistent across the whole cluster, and with the database,
- is quite expensive. It makes most sense for data which is shared
- between many users, and is updated rarely. In traditional
- stateless architectures, people often try to use the second-level
- cache for conversational state. This is always bad, and is
- especially wrong in Seam.
- </para>
- </listitem>
- <listitem>
- <para>
- The Seam conversation context is a cache of conversational state.
- Components you put into the conversation context can hold and cache
- state relating to the current user interaction.
- </para>
- </listitem>
- <listitem>
- <para>
- In particular, the
- Seam-managed persistence context (or an extended EJB container-managed
- persistence context associated with a conversation-scoped stateful
- session bean) acts as a cache of data that has been read in the
- current conversation. This cache tends to have a pretty high
- hitrate! Seam optimizes the replication of Seam-managed persistence
- contexts in a clustered environment, and there is no requirement for
- transactional consistency with the database (optimistic locking is
- sufficient) so you don't need to worry too much about the performance
- implications of this cache, unless you read thousands of objects into
- a single persistence context.
- </para>
- </listitem>
- <listitem>
- <para>
- The application can cache non-transactional state in the Seam
- application context. State kept in the application context is
- of course not visible to other nodes in the cluster.
- </para>
- </listitem>
- <listitem>
- <para>
- The application can cache transactional state using the Seam
- <literal>pojoCache</literal> component, which integrates
- JBossCache into the Seam environment. This state will be visible
- to other nodes if you run JBoss cache in a clustered mode.
- </para>
- </listitem>
- <listitem>
- <para>
- Finally, Seam lets you cache rendered fragments of a JSF page. Unlike
- the ORM second-level cache, this cache is not automatically invalidated
- when data changes, so you need to write application code to perform
- explicit invalidation, or set appropriate expiration policies.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- For more information about the second-level cache, you'll need to refer to
- the documentation of your ORM solution, since this is an extremely complex
- topic. In this section we'll discuss the use of JBossCache directly, via
- the <literal>pojoCache</literal> component, or as the page fragment cache,
- via the <literal><s:cache></literal> control.
- </para>
-
- <section>
- <title>Using JBossCache in Seam</title>
-
- <para>
- The built-in <literal>pojoCache</literal> component manages an instance
- of <literal>org.jboss.cache.aop.PojoCache</literal>. You can safely put
- any immutable Java object in the cache, and it will be replicated across
- the cluster (assuming that replication is enabled). If you want to
- keep mutable objects in the cache, you'll need to run the JBossCache
- bytecode preprocessor to ensure that changes to the objects will be
- automatically detected and replicated.
- </para>
-
- <para>
- To use <literal>pojoCache</literal>, all you need to do is put the
- JBossCache jars in the classpath, and provide a resource named
- <literal>treecache.xml</literal> with an appropriate cache configuration.
- JBossCache has many scary and confusing configuration settings, so
- we won't discuss them here. Please refer to the JBossCache documentation
- for more information.
- </para>
-
- <para>
- You can find a sample <literal>treecache.xml</literal> in
- <literal>examples/blog/resources/treecache.xml</literal>.
- </para>
-
-
- <para>
- For an EAR depoyment of Seam, we recommend that the JBossCache jars and
- configuration go directly into the EAR. Make sure you place both
- <literal>jboss-cache.jar</literal> and <literal>jgroups.jar</literal>
- in your EAR's lib folder.
- </para>
-
- <para>
- Now you can inject the cache into any Seam component:
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Name("chatroom")
+ <title>Caching</title>
+
+ <para>
+ In almost all enterprise applications, the database is the primary
+ bottleneck, and the least scalable tier of the runtime environment. People
+ from a PHP/Ruby environment will try to tell you that so-called "shared
+ nothing" architectures scale well. While that may be literally true, I
+ don't know of many interesting multi-user applications which can be
+ implemented with no sharing of resources between different nodes of the
+ cluster. What these silly people are really thinking of is a "share
+ nothing except for the database" architecture. Of course, sharing the
+ database is the primary problem with scaling a multi-user
+ application—so the claim that this architecture is highly scalable
+ is absurd, and tells you a lot about the kind of applications that these
+ folks spend most of their time working on.
+ </para>
+
+ <para>
+ Almost anything we can possibly do to share the database
+ <emphasis>less often</emphasis> is worth doing.
+ </para>
+
+ <para>
+ This calls for a cache. Well, not just one cache. A well designed Seam
+ application will feature a rich, multi-layered caching strategy that
+ impacts every layer of the application:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The database, of course, has its own cache. This is super-important,
+ but can't scale like a cache in the application tier.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Your ORM solution (Hibernate, or some other JPA implementation) has
+ a second-level cache of data from the database. This is a very
+ powerful capability, but is often misused. In a clustered
+ environment, keeping the data in the cache transactionally
+ consistent across the whole cluster, and with the database, is quite
+ expensive. It makes most sense for data which is shared between many
+ users, and is updated rarely. In traditional stateless
+ architectures, people often try to use the second-level cache for
+ conversational state. This is always bad, and is especially wrong in
+ Seam.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The Seam conversation context is a cache of conversational state.
+ Components you put into the conversation context can hold and cache
+ state relating to the current user interaction.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In particular, the Seam-managed persistence context (or an extended
+ EJB container-managed persistence context associated with a
+ conversation-scoped stateful session bean) acts as a cache of data
+ that has been read in the current conversation. This cache tends to
+ have a pretty high hitrate! Seam optimizes the replication of
+ Seam-managed persistence contexts in a clustered environment, and
+ there is no requirement for transactional consistency with the
+ database (optimistic locking is sufficient) so you don't need to
+ worry too much about the performance implications of this cache,
+ unless you read thousands of objects into a single persistence
+ context.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The application can cache non-transactional state in the Seam
+ application context. State kept in the application context is of
+ course not visible to other nodes in the cluster.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The application can cache transactional state using the Seam
+ <literal>pojoCache</literal> component, which integrates JBossCache
+ into the Seam environment. This state will be visible to other nodes
+ if you run JBoss cache in a clustered mode.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Finally, Seam lets you cache rendered fragments of a JSF page.
+ Unlike the ORM second-level cache, this cache is not automatically
+ invalidated when data changes, so you need to write application code
+ to perform explicit invalidation, or set appropriate expiration
+ policies.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ For more information about the second-level cache, you'll need to refer to
+ the documentation of your ORM solution, since this is an extremely complex
+ topic. In this section we'll discuss the use of JBossCache directly, via
+ the <literal>pojoCache</literal> component, or as the page fragment cache,
+ via the <literal><s:cache></literal> control.
+ </para>
+
+ <section>
+ <title>Using JBossCache in Seam</title>
+
+ <para>
+ The built-in <literal>pojoCache</literal> component manages an instance
+ of <literal>org.jboss.cache.aop.PojoCache</literal>. You can safely put
+ any immutable Java object in the cache, and it will be replicated
+ across the cluster (assuming that replication is enabled). If you want
+ to keep mutable objects in the cache, you'll need to run the JBossCache
+ bytecode preprocessor to ensure that changes to the objects will be
+ automatically detected and replicated.
+ </para>
+
+ <para>
+ To use <literal>pojoCache</literal>, all you need to do is put the
+ JBossCache jars in the classpath, and provide a resource named
+ <literal>treecache.xml</literal> with an appropriate cache
+ configuration. JBossCache has many scary and confusing configuration
+ settings, so we won't discuss them here. Please refer to the JBossCache
+ documentation for more information.
+ </para>
+
+ <para>
+ You can find a sample <literal>treecache.xml</literal> in
+ <literal>examples/blog/resources/treecache.xml</literal>.
+ </para>
+
+
+ <para>
+ For an EAR depoyment of Seam, we recommend that the JBossCache jars and
+ configuration go directly into the EAR. Make sure you place both
+ <literal>jboss-cache.jar</literal> and <literal>jgroups.jar</literal>
+ in your EAR's lib folder.
+ </para>
+
+ <para>Now you can inject the cache into any Seam component:</para>
+
+ <programlisting role="JAVA"><![CDATA[@Name("chatroom")
public class Chatroom {
- @In PojoCache pojoCache;
+ @In PojoCache pojoCache;
- public void join(String username) {
- try
- {
+ public void join(String username) {
+ try {
Set<String> userList = (Set<String>) pojoCache.get("chatroom", "userList");
- if (userList==null)
- {
+ if (userList==null) {
userList = new HashSet<String>();
pojoCache.put("chatroom", "userList", userList);
}
userList.put(username);
- }
- catch (CacheException ce)
- {
+ } catch (CacheException ce) {
throw new RuntimeException(ce);
}
- }
+ }
}]]></programlisting>
- <para>
- If you want to have multiple JBossCache configurations in your application,
- use <literal>components.xml</literal>:
- </para>
-
- <programlisting role="JAVA"><![CDATA[<core:pojo-cache name="myCache" cfg-resource-name="myown/cache.xml"/>]]></programlisting>
-
- </section>
-
- <section>
- <title>Page fragment caching</title>
-
- <para>
- The most interesting user of JBossCache is the <literal><s:cache></literal>
- tag, Seam's solution to the problem of page fragment caching in JSF.
- <literal><s:cache></literal> uses <literal>pojoCache</literal> internally,
- so you need to follow the steps listed above before you can use it. (Put the jars
- in the EAR, wade through the scary configuration options, etc.)
- </para>
-
- <para>
- <literal><s:cache></literal> is used for caching some rendered content which
- changes rarely. For example, the welcome page of our blog displays the recent
- blog entries:
- </para>
-
- <programlisting role="XHTML"><![CDATA[<s:cache key="recentEntries-#{blog.id}" region="welcomePageFragments">
+ <para>
+ If you want to have multiple JBossCache configurations in your
+ application, use <literal>components.xml</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[<core:pojo-cache name="myCache" cfg-resource-name="myown/cache.xml"/>]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Page fragment caching</title>
+
+ <para>
+ The most interesting user of JBossCache is the
+ <literal><s:cache></literal> tag, Seam's solution to the problem
+ of page fragment caching in JSF. <literal><s:cache></literal>
+ uses <literal>pojoCache</literal> internally, so you need to follow the
+ steps listed above before you can use it. (Put the jars in the EAR,
+ wade through the scary configuration options, etc.)
+ </para>
+
+ <para>
+ <literal><s:cache></literal> is used for caching some rendered
+ content which changes rarely. For example, the welcome page of our blog
+ displays the recent blog entries:
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[<s:cache key="recentEntries-#{blog.id}" region="welcomePageFragments">
<h:dataTable value="#{blog.recentEntries}" var="blogEntry">
<h:column>
<h3>#{blogEntry.title}</h3>
@@ -205,31 +200,34 @@
</h:dataTable>
</s:cache>]]></programlisting>
- <para>
- The <literal>key</literal> let's you have multiple cached versions of each page
- fragment. In this case, there is one cached version per blog. The
- <literal>region</literal> determines the JBossCache node that all version will
- be stored in. Different nodes may have different expiry policies. (That's the
- stuff you set up using the aforementioned scary configuration options.)
- </para>
-
- <para>
- Of course, the big problem with <literal><s:cache></literal> is that it
- is too stupid to know when the underlying data changes (for example, when the
- blogger posts a new entry). So you need to evict the cached fragment manually:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public void post() {
+ <para>
+ The <literal>key</literal> let's you have multiple cached versions of
+ each page fragment. In this case, there is one cached version per blog.
+ The <literal>region</literal> determines the JBossCache node that all
+ version will be stored in. Different nodes may have different expiry
+ policies. (That's the stuff you set up using the aforementioned scary
+ configuration options.)
+ </para>
+
+ <para>
+ Of course, the big problem with <literal><s:cache></literal> is
+ that it is too stupid to know when the underlying data changes (for
+ example, when the blogger posts a new entry). So you need to evict the
+ cached fragment manually:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public void post() {
...
entityManager.persist(blogEntry);
pojoCache.remove("welcomePageFragments", "recentEntries-" + blog.getId() );
}]]></programlisting>
-
- <para>
- Alternatively, if it is not critical that changes are immediately visible to the
- user, you could set a short expiry time on the JbossCache node.
- </para>
-
- </section>
-
+
+ <para>
+ Alternatively, if it is not critical that changes are immediately
+ visible to the user, you could set a short expiry time on the
+ JbossCache node.
+ </para>
+
+ </section>
+
</chapter>
\ No newline at end of file
More information about the seam-commits
mailing list