[jboss-cvs] JBossAS SVN: r84557 - projects/docs/community/5/Clustering_Guide/en-US.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Feb 20 11:49:24 EST 2009
Author: pferraro
Date: 2009-02-20 11:49:24 -0500 (Fri, 20 Feb 2009)
New Revision: 84557
Modified:
projects/docs/community/5/Clustering_Guide/en-US/Clustering_Guide_Entity_EJBs.xml
Log:
AS5 update - in progress
Modified: projects/docs/community/5/Clustering_Guide/en-US/Clustering_Guide_Entity_EJBs.xml
===================================================================
--- projects/docs/community/5/Clustering_Guide/en-US/Clustering_Guide_Entity_EJBs.xml 2009-02-20 16:48:25 UTC (rev 84556)
+++ projects/docs/community/5/Clustering_Guide/en-US/Clustering_Guide_Entity_EJBs.xml 2009-02-20 16:49:24 UTC (rev 84557)
@@ -2,376 +2,543 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
<chapter id="clustering-entity">
- <title>Clustered Entity EJBs</title>
- <para>In a JBoss AS cluster, the entity bean instance caches need to be kept in sync across all nodes. If an entity bean provides remote services, the service methods need to be load balanced as well.</para>
-
- <para>To use a clustered entity bean, the application does not need to do anything special, except for looking up EJB 2.x remote bean references from the clustered HA-JNDI.</para>
- <section id="clustering-entity-21">
- <title>Entity Bean in EJB 2.x</title>
- <para>First of all, it is worth noting that clustering 2.x entity beans is a bad thing to do. Its exposes elements that generally are too fine grained for use as remote objects to clustered remote objects and introduces data synchronization problems that are non-trivial. Do NOT use EJB 2.x entity bean clustering unless you fit into the sepecial case situation of read-only, or one read-write node with read-only nodes synched with the cache invalidation services.</para>
+ <title>Clustered Entity EJBs</title>
+ <para>
+ In a JBoss AS cluster, entity bean instance caches need to be kept in sync across all nodes.
+ If an entity bean provides remote services, the service methods need to be load balanced as well.
+ </para>
+
+ <section id="clustering-entity-30">
+ <title>Entity Bean in EJB 3.0</title>
+ <para>
+ In EJB 3.0, entity beans primarily serve as a persistence data model.
+ They do not provide remote services.
+ Hence, the entity bean clustering service in EJB 3.0 primarily deals with distributed caching and replication, instead of load balancing.
+ </para>
- <para>To cluster EJB 2.x entity beans, you need to add the <literal><clustered></literal> element
- to the application's <literal>jboss.xml</literal> descriptor file. Below is a typical
- <literal>jboss.xml</literal> file.</para>
- <programlisting>
-<jboss>
- <enterprise-beans>
- <entity>
- <ejb-name>nextgen.EnterpriseEntity</ejb-name>
- <jndi-name>nextgen.EnterpriseEntity</jndi-name>
- <clustered>True</clustered>
- <cluster-config>
- <partition-name>DefaultPartition</partition-name>
- <home-load-balance-policy>
- org.jboss.ha.framework.interfaces.RoundRobin
- </home-load-balance-policy>
- <bean-load-balance-policy>
- org.jboss.ha.framework.interfaces.FirstAvailable
- </bean-load-balance-policy>
- </cluster-config>
- </entity>
- </enterprise-beans>
-</jboss>
- </programlisting>
- <para>The EJB 2.x entity beans are clustered for load balanced remote invocations. All the bean
- instances are synchronized to have the same contents on all nodes.</para>
- <para>However, clustered EJB 2.x Entity Beans do not have a distributed locking mechanism or a
- distributed cache. They can only be synchronized by using row-level locking at the database level
- (see <literal><row-lock></literal> in the CMP specification) or by setting the Transaction
- Isolation Level of your JDBC driver to be <literal>TRANSACTION_SERIALIZABLE</literal>. Because there
- is no supported distributed locking mechanism or distributed cache Entity Beans use Commit Option
- "B" by default (See <literal>standardjboss.xml</literal> and the container configurations Clustered
- CMP 2.x EntityBean, Clustered CMP EntityBean, or Clustered BMP EntityBean). It is not recommended
- that you use Commit Option "A" unless your Entity Bean is read-only. (There are some design patterns
- that allow you to use Commit Option "A" with read-mostly beans. You can also take a look at the
- Seppuku pattern <ulink url="http://dima.dhs.org/misc/readOnlyUpdates.html"/>. JBoss may incorporate
- this pattern into later versions.)</para>
- <note>
- <para>If you are using Bean Managed Persistence (BMP), you are going to have to implement
- synchronization on your own. The MVCSoft CMP 2.0 persistence engine (see <ulink url="http://www.jboss.org/jbossgroup/partners.jsp"/>) provides different kinds of optimistic
- locking strategies that can work in a JBoss cluster.</para>
- </note>
- </section>
- <section id="clustering-entity-30">
- <title>Entity Bean in EJB 3.0</title>
-
- <para>In EJB 3.0, the entity beans primarily serve as a persistence data model. They do not provide
- remote services. Hence, the entity bean clustering service in EJB 3.0 primarily deals with
- distributed caching and replication, instead of load balancing.</para>
-
-
- <section id="clustering-entity-30-cache">
- <title>Configure the distributed cache</title>
- <para>To avoid round trips to the database, you can use a cache for your entities. JBoss EJB 3.0 entity beans are implemented by Hibernate, which has support for a second-level cache. The Hibernate setup used for the JBoss EJB 3.0 implementation uses JBoss Cache as its underlying second-level cache implementation. The second-level cache provides the following functionalities.</para>
- <itemizedlist>
- <listitem>
- <para>If you persist a cache enabled entity bean instance to the database via the entity
- manager the entity will inserted into the cache.</para>
- </listitem>
- <listitem>
- <para>If you update an entity bean instance and save the changes to the database via the
- entity manager the entity will updated in the cache.</para>
- </listitem>
- <listitem>
- <para>If you remove an entity bean instance from the database via the entity manager the
- entity will removed from the cache.</para>
- </listitem>
- <listitem>
- <para>If loading a cached entity from the database via the entity manager, and that entity
- does not exist in the database, it will be inserted into the cache.</para>
- </listitem>
- </itemizedlist>
- <para>The JBoss Cache service for EJB 3.0 entity beans is configured in a <literal>TreeCache</literal>
- MBean <!--(see <xref linkend="jbosscache-cache"/>) -->in the
- <literal>deploy/ejb3-entity-cache-service.xml</literal> file. The name of the cache MBean
- service is <literal>jboss.cache:service=EJB3EntityTreeCache</literal>. Below are the contents of
- the <literal>ejb3-entity-cache-service.xml</literal> file in the standard JBoss distribution.
- Again, we omitted the JGroups configuration element <literal>ClusterConfig</literal>.</para>
-<programlisting><![CDATA[
- <server>
- <mbean code="org.jboss.cache.TreeCache"
- name="jboss.cache:service=EJB3EntityTreeCache">
-
- <depends>jboss:service=Naming</depends>
- <depends>jboss:service=TransactionManager</depends>
-
- <!-- Name of cluster. Needs to be the same on all nodes in the clusters,
- in order to find each other -->
- <attribute name="ClusterName">
- ${jboss.partition.name:DefaultPartition}-EntityCache
- </attribute>
-
- <!-- Configure the TransactionManager -->
- <attribute name="TransactionManagerLookupClass">
- org.jboss.cache.JBossTransactionManagerLookup
- </attribute>
-
- <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
- <attribute name="CacheMode">REPL_SYNC</attribute>
-
- <!-- Must be true if any entity deployment uses a scoped classloader -->
- <attribute name="UseRegionBasedMarshalling">true</attribute>
- <!-- Must match the value of "useRegionBasedMarshalling" -->
- <attribute name="InactiveOnStartup">true</attribute>
-
- <attribute name="ClusterConfig">
- ... ...
- </attribute>
-
- <attribute name="InitialStateRetrievalTimeout">17500</attribute>
- <attribute name="SyncReplTimeout">17500</attribute>
- <attribute name="LockAcquisitionTimeout">15000</attribute>
-
- <attribute name="EvictionPolicyClass">
- org.jboss.cache.eviction.LRUPolicy
- </attribute>
-
- <!-- Specific eviction policy configurations. This is LRU -->
- <attribute name="EvictionPolicyConfig">
- <config>
- <attribute name="wakeUpIntervalSeconds">5</attribute>
- <!-- Cache wide default -->
- <region name="/_default_">
- <attribute name="maxNodes">5000</attribute>
- <attribute name="timeToLiveSeconds">1000</attribute>
- </region>
- </config>
- </attribute>
- </mbean>
-</server>
-]]>
-</programlisting>
-
-<para>This is a replicated cache, so, if running within a cluster, and the cache is updated, changes to the entries in one node will be replicated to the corresponding entries in the other nodes in the cluster.
-</para>
-
- <para><!--As discussed in <xref linkend="jbosscache-cache"/>,--> JBoss Cache allows you to specify
- timeouts to cached entities. Entities not accessed within a certain amount of time are dropped
- from the cache in order to save memory. The above configuration sets up a default configuration region that says that at most the cache will hold 5000 nodes, after which nodes will start being evicted from memory, least-recently used nodes last. Also, if any node has not been accessed within the last 1000 seconds, it will be evicted from memory. In general, a node in the cache represents a cached item (entity, collection, or query result set), although there are also a few other node that are used for internal purposes. If the above values of 5000 maxNodes and 1000 idle seconds are invalid for your application(s), you can change the cache-wide defaults. You can also add separate eviction regions for each of your entities; more on this below.
- </para>
- <para>Now, we have JBoss Cache configured to support distributed caching of EJB 3.0 entity beans. We still have to configure individual entity beans to use the cache service.</para>
- </section>
- <section id="clustering-entity-30-bean">
- <title>Configure the entity beans for cache</title>
- <para>You define your entity bean classes the normal way. Future versions of JBoss EJB 3.0 will
- support annotating entities and their relationship collections as cached, but for now you have
- to configure the underlying hibernate engine directly. Take a look at the
- <literal>persistence.xml</literal> file, which configures the caching options for hibernate
- via its optional <literal>property</literal> elements. The following element in
- <literal>persistence.xml</literal> defines that caching should be enabled:</para>
- <programlisting>
-<!-- Clustered cache with TreeCache -->
-<property name="cache.provider_class">
- org.jboss.ejb3.entity.TreeCacheProviderHook
-</property>
- </programlisting>
- <para>The following property element defines the object name of the cache to be used, i.e., the name of the TreeCache MBean shown above.</para>
- <programlisting>
-<property name="treecache.mbean.object_name">
- jboss.cache:service=EJB3EntityTreeCache
-</property>
- </programlisting>
-<para>
- Finally, you should give a “region_prefix” to this configuration. This ensures that all cached items associated with this persistence.xml are properly grouped together in JBoss Cache. The jboss.cache:service=EJB3EntityTreeCache cache is a shared resource, potentially used by multiple persistence units. The items cached in that shared cache need to be properly grouped to allow the cache to properly manage classloading.
- <property name="hibernate.cache.region_prefix" value="myprefix"/>
-</para>
-<para>
- If you do not provide a region prefix, JBoss will automatically provide one for you, building it up from the name of the EAR (if any) and the name of the JAR that includes the persistence.xml. For example, a persistence.xml packaged in foo.ear, bar.jar would be given “foo_ear,bar_jar” as its region prefix. This is not a particularly friendly region prefix if you need to use it to set up specialized eviction regions (see below), so specifying your own region prefix is recommended.
-</para>
-
-
-
-
-
-<para>Next we need to configure what entities be cached. The default is to not cache anything, even with the settings shown above. We use the <literal>@org.hibernate.annotations.Cache</literal> annotation to tag entity beans that needs to be cached.</para>
- <programlisting>
+ <section id="clustering-entity-30-cache">
+ <title>Configure the distributed cache</title>
+ <para>
+ To avoid round trips to the database, you can use a cache for your entities.
+ JBoss EJB 3.0 entity beans are implemented by Hibernate, which has support for a second-level cache.
+ The second-level cache provides the following functionalities:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ If you persist a cache-enabled entity bean instance to the database via the entity manager, the entity will be inserted into the cache.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you update an entity bean instance, and save the changes to the database via the entity manager, the entity will be updated in the cache.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you remove an entity bean instance from the database via the entity manager, the entity will be removed from the cache.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If loading a cached entity from the database via the entity manager, and that entity does not exist in the database, it will be inserted into the cache.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ As well as a region for caching entities, the second-level cache also contains regions for caching collections, queries, and timestamps.
+ The Hibernate setup used for the JBoss EJB 3.0 implementation uses JBoss Cache as its underlying second-level cache implementation.
+ </para>
+ <para>
+ Configuration of a the second-level cache is done via your EJB3 deployment's persistence.xml.
+ </para>
+ <para>
+ e.g.
+ </para>
+ <programlisting><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
+ <persistence-unit name="tempdb" transaction-type="JTA">
+ <jta-data-source>java:/DefaultDS</jta-data-source>
+ <properties>
+ <property name="hibernate.cache.use_second_level_cache" value="true"/>
+ <property name="hibernate.cache.use_query_cache" value="true"/>
+ <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
+ <!-- region factory specific properties -->
+ <property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
+ <property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
+ <property name="hibernate.cache.region.jbc2.cfg.collection" value="mvcc-entity"/>
+ </properties>
+ </persistence-unit>
+</persistence>
+]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term>hibernate.cache.use_second_level_cache</term>
+ <listitem>
+ <para>
+ Enables second-level caching of entities and collections.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>hibernate.cache.use_query_cache</term>
+ <listitem>
+ <para>
+ Enables second-level caching of queries.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>hibernate.cache.region.factory_class</term>
+ <listitem>
+ <para>
+ Defines the <literal>RegionFactory</literal> implementation that dictates region-specific caching behavior.
+ Hibernate ships with 2 types of JBoss Cache-based second-level caches: shared and multiplexed.
+ </para>
+ <para>
+ A shared region factory uses the same Cache for all cache regions - much like the legacy CacheProvider implementation in older Hibernate versions.
+ </para>
+ <para>Hibernate ships with 2 shared region factory implementations:</para>
+ <variablelist>
+ <varlistentry>
+ <term>org.hibernate.cache.jbc2.SharedJBossCacheRegionFactory</term>
+ <listitem>
+ <para>
+ Uses a single JBoss Cache configuration, from a newly instantiated CacheManager, for all cache regions.
+ </para>
+ <para>
+ <table border="1">
+ <caption>Additional properties for SharedJBossCacheRegionFactory</caption>
+ <tr>
+ <th>Property</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.shared</td>
+ <td>treecache.xml</td>
+ <td>The classpath or filesystem resource containing the JBoss Cache configuration settings.</td>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.jgroups.stacks</td>
+ <td>org/hibernate/cache/jbc2/builder/jgroups-stacks.xml</td>
+ <td>The classpath or filesystem resource containing the JGroups protocol stack configurations.</td>
+ </tr>
+ </table>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>org.hibernate.cache.jbc2.JndiSharedJBossCacheRegionFactory</term>
+ <listitem>
+ <para>
+ Uses a single JBoss Cache configuration, from an existing CacheManager bound to JNDI, for all cache regions.
+ </para>
+ <para>
+ <table border="1">
+ <caption>Additional properties for JndiSharedJBossCacheRegionFactory</caption>
+ <tr>
+ <th>Property</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.shared</td>
+ <td><emphasis>Required</emphasis></td>
+ <td>JNDI name to which the shared <literal>Cache</literal> instance is bound.</td>
+ </tr>
+ </table>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ A multiplexed region factory uses separate Cache instances, using optimized configurations for each cache region.
+ </para>
+ <table border="1">
+ <caption>Common properties for multiplexed region factory implementations</caption>
+ <tr>
+ <th>Property</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.entity</td>
+ <td>optimistic-entity</td>
+ <td>
+ The JBoss Cache configuration used for the entity cache region.
+ Alternative configurations: mvcc-entity, pessimistic-entity, mvcc-entity-repeatable, optimistic-entity-repeatable, pessimistic-entity-repeatable
+ </td>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.collection</td>
+ <td>optimistic-entity</td>
+ <td>
+ The JBoss Cache configuration used for the collection cache region.
+ The collection cache region typically uses the same configuration as the entity cache region.
+ </td>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.query</td>
+ <td>local-query</td>
+ <td>
+ The JBoss Cache configuration used for the query cache region.
+ By default, cached query results are not replicated.
+ Alternative configurations: replicated-query
+ </td>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.ts</td>
+ <td>timestamps-cache</td>
+ <td>
+ The JBoss Cache configuration used for the timestamp cache region.
+ If query caching is used, the corresponding timestamp cache must be replicating, even if the query cache is non-replicating.
+ The timestamp cache region must never share the same cache as the query cache.
+ </td>
+ </tr>
+ </table>
+ <para>Hibernate ships with 2 shared region factory implementations:</para>
+ <variablelist>
+ <varlistentry>
+ <term>org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory</term>
+ <listitem>
+ <para>
+ Uses separate JBoss Cache configurations, from a newly instantiated CacheManager, per cache region.
+ </para>
+ <table border="1">
+ <caption>Additional properties for MultiplexedJBossCacheRegionFactory</caption>
+ <tr>
+ <th>Property</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.configs</td>
+ <td>org/hibernate/cache/jbc2/builder/jbc2-configs.xml</td>
+ <td>The classpath or filesystem resource containing the JBoss Cache configuration settings.</td>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cfg.jgroups.stacks</td>
+ <td>org/hibernate/cache/jbc2/builder/jgroups-stacks.xml</td>
+ <td>The classpath or filesystem resource containing the JGroups protocol stack configurations.</td>
+ </tr>
+ </table>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory</term>
+ <listitem>
+ <para>
+ Uses separate JBoss Cache configurations, from a JNDI-bound CacheManager, see <xref linkend="clustering-blocks-jbc-cachemanager"/>, per cache region.
+ </para>
+ <para>
+ <table border="1">
+ <caption>Additional properties for JndiMultiplexedJBossCacheRegionFactory</caption>
+ <tr>
+ <th>Property</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>hibernate.cache.region.jbc2.cachefactory</td>
+ <td><emphasis>Required</emphasis></td>
+ <td>JNDI name to which the <literal>CacheManager</literal> instance is bound.</td>
+ </tr>
+ </table>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Now, we have JBoss Cache configured to support distributed caching of EJB 3.0 entity beans.
+ We still have to configure individual entity beans to use the cache service.
+ </para>
+ </section>
+ <section id="clustering-entity-30-bean">
+ <title>Configure the entity beans for cache</title>
+<!--
+***************************
+This section is in progress
+***************************
+-->
+ <para>
+ Next we need to configure which entities to cache.
+ The default is to not cache anything, even with the settings shown above.
+ We use the <literal>@org.hibernate.annotations.Cache</literal> annotation to tag entity beans that needs to be cached.
+ </para>
+ <programlisting><![CDATA[
@Entity
- at Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
-public class Account implements Serializable {
- // ... ...
+ at Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
+public class Account implements Serializable
+{
+ // ... ...
}
- </programlisting>
- <para>A very simplified rule of thumb is that you will typically want to do caching for objects that
- rarely change, and which are frequently read. You can fine tune the cache for each entity bean in the <literal>ejb3-entity-cache-service.xml</literal> configuration file. For instance, you can specify the size of the cache. If there are too many objects in the cache, the cache could evict oldest objects (or least used objects, depending on configuration) to make room for new objects. Assuming the region_prefix specified in <literal>persistence.xml</literal> was myprefix, the default name of the cache region for the <literal>com.mycompany.entities.Account</literal> entity bean <literal>/myprefix/com/mycompany/entities/Account</literal>.</para>
- <programlisting><![CDATA[
-<server>
- <mbean code="org.jboss.cache.TreeCache"
- name="jboss.cache:service=EJB3EntityTreeCache">
- ... ...
- <attribute name="EvictionPolicyConfig">
- <config>
- <attribute name="wakeUpIntervalSeconds">5</attribute>
- <region name="/_default_">
- <attribute name="maxNodes">5000</attribute>
- <attribute name="timeToLiveSeconds">1000</attribute>
- </region>
- <!-- Separate eviction rules for Account entities -->
- <region name="/myprefix/com/mycompany/entities/Account">
- <attribute name="maxNodes">10000</attribute>
- <attribute name="timeToLiveSeconds">5000</attribute>
- </region>
- ... ...
- </config>
- </attribute>
- </mbean>
-</server>]]>
-</programlisting>
-
-
-<para>
- If you do not specify a cache region for an entity bean class, all instances of this class will be cached in the <literal>/_default</literal> region as defined above. The @Cache annotation exposes an optional attribute “region” that lets you specify the cache region where an entity is to be stored, rather than having it be automatically be created from the fully-qualified class name of the entity class.
-</para>
-<programlisting>
+]]></programlisting>
+ <para>
+ A very simplified rule of thumb is that you will typically want to do caching for objects that rarely change, and which are frequently read.
+ You can fine tune the cache for each entity bean in the appropriate JBoss Cache configuration file, e.g. jboss-cache-manager-jboss-beans.xml.
+ For instance, you can specify the size of the cache.
+ If there are too many objects in the cache, the cache could evict oldest objects (or least used objects, depending on configuration) to make room for new objects.
+ Assuming the region_prefix specified in <literal>persistence.xml</literal> was <literal>myprefix</literal>, the default name of the cache region for the <literal>com.mycompany.entities.Account</literal> entity bean would be <literal>/myprefix/com/mycompany/entities/Account</literal>.
+ </para>
+ <programlisting><![CDATA[
+<bean name="..." class="org.jboss.cache.config.Configuration">
+ ... ...
+ <property name="evictionConfig">
+ <bean class="org.jboss.cache.config.EvictionConfig">
+ <property name="wakeupInterval">5000</property>
+ <!-- Overall default -->
+ <property name="defaultEvictionRegionConfig">
+ <bean class="org.jboss.cache.config.EvictionRegionConfig">
+ <property name="regionName">/</property>
+ <property name="evictionAlgorithmConfig">
+ <bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <property name="maxNodes">10000</property>
+ <!-- And, evict any node that hasn't been accessed in this many seconds -->
+ <property name="timeToLiveSeconds">1000</property>
+ <!-- Don't evict a node that's been accessed within this many seconds.
+ Set this to a value greater than your max expected transaction length. -->
+ <property name="minTimeToLiveSeconds">120</property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ <property name="evictionRegionConfigs">
+ <list>
+ <bean class="org.jboss.cache.config.EvictionRegionConfig">
+ <property name="regionName">/com/mycompany/entities/Account</property>
+ <property name="evictionAlgorithmConfig">
+ <bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
+ <property name="maxNodes">10000</property>
+ <property name="timeToLiveSeconds">5000</property>
+ <property name="minTimeToLiveSeconds">120</property>
+ </bean>
+ </property>
+ </bean>
+ ... ...
+ </list>
+ </property>
+ </bean>
+ </property>
+</bean>
+]]></programlisting>
+ <para>
+ If you do not specify a cache region for an entity bean class, all instances of this class will be cached in the <literal>/_default</literal> region as defined above. The @Cache annotation exposes an optional attribute “region” that lets you specify the cache region where an entity is to be stored, rather than having it be automatically be created from the fully-qualified class name of the entity class.
+ </para>
+ <programlisting><![CDATA[
@Entity
- at Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL,
-region=”Account”)
-public class Account implements Serializable {
-// ... ...
+ at Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = ”Account”)
+public class Account implements Serializable
+{
+ // ... ...
}
-</programlisting>
-<para>The eviction configuration would then become:</para>
-<programlisting><![CDATA[
-<server>
- <mbean code="org.jboss.cache.TreeCache"
- name="jboss.cache:service=EJB3EntityTreeCache">
- ... ...
- <attribute name="EvictionPolicyConfig">
- <config>
- <attribute name="wakeUpIntervalSeconds">5</attribute>
- <region name="/_default_">
- <attribute name="maxNodes">5000</attribute>
- <attribute name="timeToLiveSeconds">1000</attribute>
- </region>
- <!-- Separate eviction rules for Account entities -->
- <region name="/myprefix/Account">
- <attribute name="maxNodes">10000</attribute>
- <attribute name="timeToLiveSeconds">5000</attribute>
- </region>
- ... ...
- </config>
- </attribute>
- </mbean>
-</server>]]>
-</programlisting>
-
-</section>
+]]></programlisting>
+ <para>
+ The eviction configuration would then become:
+ </para>
+ <programlisting><![CDATA[
+<server>
+ <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache">
+ ... ...
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <region name="/_default_">
+ <attribute name="maxNodes">5000</attribute>
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ </region>
+ <!-- Separate eviction rules for Account entities -->
+ <region name="/myprefix/Account">
+ <attribute name="maxNodes">10000</attribute>
+ <attribute name="timeToLiveSeconds">5000</attribute>
+ </region>
+ ... ...
+ </config>
+ </attribute>
+ </mbean>
+</server>
+]]></programlisting>
+ </section>
-
-<section><title>Query result caching</title>
-<para>
- The EJB3 Query API also provides means for you to save in the second-level cache the results (i.e., collections of primary keys of entity beans, or collections of scalar values) of specified queries. Here we show a simple example of annotating a bean with a named query, also providing the Hibernate-specific hints that tells Hibernate to cache the query.
-</para>
-<para>
- First, in persistence.xml you need to tell Hibernate to enable query caching:
-</para>
-<screen><property name="hibernate.cache.use_query_cache" value="true"/></screen>
-<para>
-Next, you create a named query associated with an entity, and tell Hibernate you want to cache the results of that query:
-</para>
-<programlisting><![CDATA[
+ <section>
+ <title>Query result caching</title>
+<!--
+***************************
+This section is in progress
+***************************
+-->
+ <para>
+ The EJB3 Query API also provides means for you to save in the second-level cache the results (i.e., collections of primary keys of entity beans, or collections of scalar values) of specified queries. Here we show a simple example of annotating a bean with a named query, also providing the Hibernate-specific hints that tells Hibernate to cache the query.
+ </para>
+ <para>
+ First, in persistence.xml you need to tell Hibernate to enable query caching:
+ </para>
+ <screen><property name="hibernate.cache.use_query_cache" value="true"/></screen>
+ <para>
+ Next, you create a named query associated with an entity, and tell Hibernate you want to cache the results of that query:
+ </para>
+ <programlisting><![CDATA[
@Entity
- at Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL,
-region=”Account”)
- at NamedQueries({
- at NamedQuery(name="account.bybranch",
-query="select acct from Account as acct where acct.branch = ?1",
-hints={@QueryHint(name="org.hibernate.cacheable",value="true")})
+ at Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = ”Account”)
+ at NamedQueries(
+{
+ @NamedQuery(
+ name = "account.bybranch",
+ query = "select acct from Account as acct where acct.branch = ?1",
+ hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }
+ )
})
-public class Account implements Serializable {
-// ... ...
-}]]>
-</programlisting>
-
-<para>
- The @NamedQueries, @NamedQuery and @QueryHint annotations are all in the javax.persistence package.See the Hibernate and EJB3 documentation for more on how to use EJB3 queries and on how to instruct EJB3 to cache queries.
-</para>
-<para>
-By default, Hibernate stores query results in JBoss Cache in a region named {region_prefix}/org/hibernate/cache/StandardQueryCache. Based on this, you can set up separate eviction handling for your query results. So, if the region prefix were set to myprefix in persistence.xml, you could, for example, create this sort of eviction handling:
-</para>
-
-<programlisting>
-<![CDATA[
+public class Account implements Serializable
+{
+ // ... ...
+}
+]]></programlisting>
+ <para>
+ The @NamedQueries, @NamedQuery and @QueryHint annotations are all in the javax.persistence package.
+ See the Hibernate and EJB3 documentation for more on how to use EJB3 queries and on how to instruct EJB3 to cache queries.
+ </para>
+ <para>
+ By default, Hibernate stores query results in JBoss Cache in a region named {region_prefix}/org/hibernate/cache/StandardQueryCache. Based on this, you can set up separate eviction handling for your query results. So, if the region prefix were set to myprefix in persistence.xml, you could, for example, create this sort of eviction handling:
+ </para>
+ <programlisting><![CDATA[
<server>
- <mbean code="org.jboss.cache.TreeCache"
- name="jboss.cache:service=EJB3EntityTreeCache">
- ... ...
- <attribute name="EvictionPolicyConfig">
- <config>
- <attribute name="wakeUpIntervalSeconds">5</attribute>
- <region name="/_default_">
- <attribute name="maxNodes">5000</attribute>
- <attribute name="timeToLiveSeconds">1000</attribute>
- </region>
- <!-- Separate eviction rules for Account entities -->
- <region name="/myprefix/Account">
- <attribute name="maxNodes">10000</attribute>
- <attribute name="timeToLiveSeconds">5000</attribute>
- </region>
- <!-- Cache queries for 10 minutes -->
- <region name="/myprefix/org/hibernate/cache/StandardQueryCache">
- <attribute name="maxNodes">100</attribute>
- <attribute name="timeToLiveSeconds">600</attribute>
- </region>
- ... ...
- </config>
- </attribute>
- </mbean>
+ <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache">
+ ... ...
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <region name="/_default_">
+ <attribute name="maxNodes">5000</attribute>
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ </region>
+ <!-- Separate eviction rules for Account entities -->
+ <region name="/myprefix/Account">
+ <attribute name="maxNodes">10000</attribute>
+ <attribute name="timeToLiveSeconds">5000</attribute>
+ </region>
+ <!-- Cache queries for 10 minutes -->
+ <region name="/myprefix/org/hibernate/cache/StandardQueryCache">
+ <attribute name="maxNodes">100</attribute>
+ <attribute name="timeToLiveSeconds">600</attribute>
+ </region>
+ ... ...
+ </config>
+ </attribute>
+ </mbean>
</server>
- ]]>
-</programlisting>
+]]></programlisting>
+ <para>
+ The @NamedQuery.hints attribute shown above takes an array of vendor-specific @QueryHints as a value. Hibernate accepts the “org.hibernate.cacheRegion” query hint, where the value is the name of a cache region to use instead ofthe default /org/hibernate/cache/StandardQueryCache. For example:
+ </para>
+ <programlisting><![CDATA[
+ at Entity
+ at Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = ”Account”)
+ at NamedQueries(
+{
+ @NamedQuery(
+ name = "account.bybranch",
+ query = "select acct from Account as acct where acct.branch = ?1",
+ hints =
+ {
+ @QueryHint(name = "org.hibernate.cacheable", value = "true"),
+ @QueryHint(name = ”org.hibernate.cacheRegion, value = ”Queries”)
+ }
+ )
+})
+public class Account implements Serializable
+{
+ // ... ...
+}
+]]></programlisting>
+ <para>
+ The related eviction configuration:
+ </para>
+ <programlisting><![CDATA[
+<server>
+ <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache">
+ ... ...
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <region name="/_default_">
+ <attribute name="maxNodes">5000</attribute>
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ </region>
+ <!-- Separate eviction rules for Account entities -->
+ <region name="/myprefix/Account">
+ <attribute name="maxNodes">10000</attribute>
+ <attribute name="timeToLiveSeconds">5000</attribute>
+ </region>
+ <!-- Cache queries for 10 minutes -->
+ <region name="/myprefix/Queries">
+ <attribute name="maxNodes">100</attribute>
+ <attribute name="timeToLiveSeconds">600</attribute>
+ </region>
+ ... ...
+ </config>
+ </attribute>
+ </mbean>
+</server>
+]]></programlisting>
+ </section>
+ </section>
+
+ <section id="clustering-entity-21">
+ <title>Entity Bean in EJB 2.x</title>
+ <para>
+ First of all, it is worth noting that clustering 2.x entity beans is a bad thing to do.
+ Its exposes elements that generally are too fine grained for use as remote objects to clustered remote objects and introduces data synchronization problems that are non-trivial.
+ Do NOT use EJB 2.x entity bean clustering unless you fit into the sepecial case situation of read-only, or one read-write node with read-only nodes synched with the cache invalidation services.
+ </para>
-<para>
- The @NamedQuery.hints attribute shown above takes an array of vendor-specific @QueryHints as a value. Hibernate accepts the “org.hibernate.cacheRegion” query hint, where the value is the name of a cache region to use instead ofthe default /org/hibernate/cache/StandardQueryCache. For example:
-</para>
-<programlisting><![CDATA[
- @Entity
- @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL,
- region=”Account”)
- @NamedQueries({
- @NamedQuery(name="account.bybranch",
- query="select acct from Account as acct where acct.branch = ?1",
- hints={@QueryHint(name="org.hibernate.cacheable",value="true"),
- @QueryHint(name=”org.hibernate.cacheRegion,value=”Queries”)
- })
- })
- public class Account implements Serializable {
- // ... ...
- }]]>
-</programlisting>
- <para>
- The related eviction configuration:
-</para>
-<programlisting><![CDATA[
-<server>
- <mbean code="org.jboss.cache.TreeCache"
- name="jboss.cache:service=EJB3EntityTreeCache">
- ... ...
- <attribute name="EvictionPolicyConfig">
- <config>
- <attribute name="wakeUpIntervalSeconds">5</attribute>
- <region name="/_default_">
- <attribute name="maxNodes">5000</attribute>
- <attribute name="timeToLiveSeconds">1000</attribute>
- </region>
- <!-- Separate eviction rules for Account entities -->
- <region name="/myprefix/Account">
- <attribute name="maxNodes">10000</attribute>
- <attribute name="timeToLiveSeconds">5000</attribute>
- </region>
- <!-- Cache queries for 10 minutes -->
- <region name="/myprefix/Queries">
- <attribute name="maxNodes">100</attribute>
- <attribute name="timeToLiveSeconds">600</attribute>
- </region>
- ... ...
- </config>
- </attribute>
- </mbean>
-</server>]]>
-</programlisting>
-
- </section>
- </section>
-
+ <para>
+ To use a clustered entity bean, the application does not need to do anything special, except for looking up EJB 2.x remote bean references from the clustered HA-JNDI.
+ </para>
+ <para>
+ To cluster EJB 2.x entity beans, you need to add the <literal><clustered></literal> element to the application's <literal>jboss.xml</literal> descriptor file.
+ Below is a typical <literal>jboss.xml</literal> file.
+ </para>
+ <programlisting><![CDATA[
+<jboss>
+ <enterprise-beans>
+ <entity>
+ <ejb-name>nextgen.EnterpriseEntity</ejb-name>
+ <jndi-name>nextgen.EnterpriseEntity</jndi-name>
+ <clustered>True</clustered>
+ <cluster-config>
+ <partition-name>DefaultPartition</partition-name>
+ <home-load-balance-policy>org.jboss.ha.framework.interfaces.RoundRobin</home-load-balance-policy>
+ <bean-load-balance-policy>org.jboss.ha.framework.interfaces.FirstAvailable</bean-load-balance-policy>
+ </cluster-config>
+ </entity>
+ </enterprise-beans>
+</jboss>
+]]></programlisting>
+ <para>
+ The EJB 2.x entity beans are clustered for load balanced remote invocations.
+ All the bean instances are synchronized to have the same contents on all nodes.
+ </para>
+ <para>
+ However, clustered EJB 2.x Entity Beans do not have a distributed locking mechanism or a distributed cache.
+ They can only be synchronized by using row-level locking at the database level (see <literal><row-lock></literal> in the CMP specification) or by setting the Transaction Isolation Level of your JDBC driver to be <literal>TRANSACTION_SERIALIZABLE</literal>.
+ Because there is no supported distributed locking mechanism or distributed cache Entity Beans use Commit Option "B" by default (See <literal>standardjboss.xml</literal> and the container configurations Clustered CMP 2.x EntityBean, Clustered CMP EntityBean, or Clustered BMP EntityBean).
+ It is not recommended that you use Commit Option "A" unless your Entity Bean is read-only.
+ (There are some design patterns that allow you to use Commit Option "A" with read-mostly beans.
+ You can also take a look at the Seppuku pattern <ulink url="http://dima.dhs.org/misc/readOnlyUpdates.html"/>.
+ JBoss may incorporate this pattern into later versions.)
+ </para>
+ <note>
+ <para>
+ If you are using Bean Managed Persistence (BMP), you are going to have to implement synchronization on your own.
+ The MVCSoft CMP 2.0 persistence engine (see <ulink url="http://www.jboss.org/jbossgroup/partners.jsp"/>) provides different kinds of optimistic locking strategies that can work in a JBoss cluster.
+ </para>
+ </note>
+ </section>
</chapter>
More information about the jboss-cvs-commits
mailing list