[HHH-3390] Document READ_COMMITTED vs REPEATABLE_READ

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14959 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Brian Stansberry 2008-07-18 19:39:34 +00:00
parent 27dfaa3fef
commit 53cf8e8925
2 changed files with 162 additions and 13 deletions

View File

@ -16,7 +16,7 @@
~
~ Red Hat Author(s): Brian Stansberry
-->
<chapter id="concepts">
<chapter id="concepts" revision="2">
<title>Core Concepts</title>
@ -271,7 +271,7 @@
even if the change made to the entity instance would not have affected
the query result. It is not performant for Hibernate to try to
determine if the entity change would have affected the query result,
so the safe choice is to invaldiate the query. See
so the safe choice is to invalidate the query. See
<xref linkend="concepts-data-types-timestamps"/> for more on query
invalidation.
</para>
@ -405,7 +405,7 @@
</sect2>
</sect1>
<sect1 id="concepts-cache-attributes" revision="1">
<sect1 id="concepts-cache-attributes" revision="2">
<title>Key JBoss Cache Behaviors</title>
<para>
@ -548,7 +548,7 @@
</sect2>
<sect2 id="concepts-cache-attr-lock" revision="1">
<sect2 id="concepts-cache-attr-lock" revision="2">
<title>Locking Scheme</title>
<para>
@ -557,13 +557,82 @@
discussion of these options. In the Second Level Cache use case, the
main benefit of optimistic locking is that updates of cached entities
by one transaction do not block reads of the cached entity by other
transactions, yet REPEATABLE_READ semantics are preserved. Optimistic
locking has a higher level of runtime overhead, however.
transactions, yet REPEATABLE_READ semantics are preserved.
</para>
<para>
If you are using optimistic locking and data versioning in Hibernate
for your entities, you should use it in the entity cache as well.
If you are not using data versioning, pessimistic locking should be
a better choice. Optimistic locking has a higher level of runtime overhead
than pessimistic locking, and in most Second Level Cache use cases a
REPEATABLE_READ semantic from the cache is not required (see
<xref linkend="concepts-cache-attr-isolation"/> for details on why not).
</para>
</sect2><sect2 id="concepts-cache-attr-isolation" revision="1">
<title>Isolation Level</title>
<para>
If the PESSIMISTIC node locking scheme is used, JBoss Cache supports a number of
different isolation level configurations that specify how different
transactions coordinate the locking of nodes in the cache. These
are somewhat analogous to database isolation levels; see the
<emphasis>JBoss Cache User Guide</emphasis> for an in depth
discussion of these options. For the Second Level Cache use case,
only two are valid: READ_COMMITTED and REPEATABLE_READ. In both cases,
cache reads do not block for other reads. In both cases a transaction
that writes to a node in the cache tree will hold an exclusive lock on
that node until the transaction commits, causing other transactions
that wish to read the node to block. In the REPEATABLE_READ case,
the read lock held by an uncommitted transaction that has read a node
will cause another transaction wishing to write to that node to block
until the read transaction commits. This ensures the reader transaction
can read the node again and get the same results, i.e. have a repeatable read.
</para>
<para>
READ_COMMITTED allows the greatest concurrency, since reads don't
block each other and also don't block a write.
</para>
<para>
If the OPTIMISTIC node locking scheme is used, any isolation level
configuration is ignored by the cache. Optimistic locking provides a
repeatable read semantic but does not cause writes to block for reads.
</para>
<para>
In most cases, a REPEATABLE_READ setting on the cache is not needed,
even if the application wants repeatable read semantics. This is
because the Second Level Cache is just that -- a secondary cache.
The primary cache for an entity or collection is the Hibernate
<literal>Session</literal> object itself. Once an entity or collection
is read from the second level cache, it is cached in the
<literal>Session</literal> for the life of the transaction. Subsequent
reads of that entity/collection will be resolved from the
<literal>Session</literal> cache itself -- there will be no repeated
read of the Second Level Cache by that transaction. So, there is no
benefit to a REPEATABLE_READ configuration in the Second Level Cache.
</para>
<para>
The only exception to this is if the application uses
<literal>Session</literal>'s <literal>evict()</literal> or
<literal>clear()</literal> methods to remove data from the
<literal>Session</literal> cache <emphasis>and</emphasis>
during the course of the same transaction wants
to read that same data again <emphasis>with a repeatable read
semantic</emphasis>.
</para>
<para>
Note that for query and timestamp caches, the behavior of the
Hibernate/JBC integration will not allow repeatable read semantics
even if JBC is configured for REPEATABLE_READ. A cache read will
not result in a read lock in the cache being held for the life
of the transaction. So, for these caches there is no benefit to a
REPEATABLE_READ configuration.
</para>
</sect2>

View File

@ -16,7 +16,7 @@
~
~ Red Hat Author(s): Brian Stansberry
-->
<chapter id="configuration">
<chapter id="configuration" revision="2">
<title>Configuration</title>
@ -30,7 +30,7 @@
need to worry about is the <literal>SessionFactory</literal> configuration.
</para>
<sect1 id="sessionfactory" revision="1">
<sect1 id="sessionfactory" revision="2">
<title>Configuring the Hibernate Session Factory</title>
<sect2 id="sessionfactory-overview" revision="1">
@ -380,12 +380,12 @@ hibernate.cache.region.factory_class=
</para>
</sect2>
<sect2 id="sessionfactory-multiplexed-jndi" revision="1">
<sect2 id="sessionfactory-multiplexed-jndi" revision="2">
<title>The <literal>JndiMultiplexedJBossCacheRegionFactory</literal></title>
<para>
The <literal>JndiMultiplexedJBossCacheRegionFactory</literal>
supports an additional configuration option:
supports the following additional configuration options:
</para>
<variablelist>
@ -399,8 +399,53 @@ hibernate.cache.region.factory_class=
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>hibernate.cache.region.jbc2.cfg.entity</literal></term>
<listitem>
<para>
Name of the configuration that should be used for entity caches.
Default value is <literal>optimistic-entity</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>hibernate.cache.region.jbc2.cfg.collection</literal></term>
<listitem>
<para>
Name of the configuration that should be used for collection caches.
No default value, as by default we try to use the same JBoss Cache
instance that is used for entity caching.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>hibernate.cache.region.jbc2.cfg.ts</literal></term>
<listitem>
<para>
Name of the configuration that should be used for timestamp caches.
Default value is <literal>timestamps-cache</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>hibernate.cache.region.jbc2.cfg.query</literal></term>
<listitem>
<para>
Name of the configuration that should be used for query caches.
By default, tries to use the same cache as is used for
entity caching. If there is no entity cache, the default
value is <literal>local-query</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
See <xref linkend="sessionfactory-multiplexed"/> for a discussion of
how the various <literal>hibernate.cache.region.jbc2.cfg</literal>
options combine to determine what JBoss Cache instances are used.
</para>
<para>
The <literal>JndiMultiplexedJBossCacheRegionFactory</literal> requires
that the JBoss Cache <literal>CacheManager</literal> is already
@ -409,11 +454,12 @@ hibernate.cache.region.factory_class=
and bound in JNDI before the Hibernate <literal>SessionFactory</literal>
is created.
</para>
</sect2>
</sect1>
<sect1 id="jbc-config" revision="1">
<sect1 id="jbc-config" revision="2">
<title>Configuring JBoss Cache</title>
@ -500,7 +546,7 @@ hibernate.cache.region.factory_class=
</sect2>
<sect2 id="jbc-config-detail" revision="1">
<sect2 id="jbc-config-detail" revision="2">
<title>JBoss Cache Configuration Details</title>
<para>
@ -556,6 +602,29 @@ hibernate.cache.region.factory_class=
</sect3>
<sect3 id="jbc-config-isolation" revision="1">
<title>IsolationLevel</title>
<para>
The JBoss Cache <emphasis>IsolationLevel</emphasis> attribute
configures whether READ_COMMITTED or REPEATABLE_READ semantics
are needed if pessimistic locking is used. It has no effect if
optimistic locking is used. See <xref linkend="concepts-cache-attr-isolation"/>
for a discussion of isolation levels.
</para>
<para>
The IsolationLevel is configured as follows:
</para>
<programlisting><![CDATA[<!-- Isolation level:
READ_COMMITTED
REPEATABLE_READ
-->
<attribute name="IsolationLevel">READ_COMMITTED</attribute>]]></programlisting>
</sect3>
<sect3 id="jbc-config-jgroups" revision="1">
<title>JGroups <literal>Channel</literal> Configuration</title>
@ -669,7 +738,7 @@ hibernate.cache.region.factory_class=
</sect2>
<sect2 id="jbc-config-multiple-std" revision="1">
<sect2 id="jbc-config-multiple-std" revision="2">
<title>Standard JBoss Cache Configurations</title>
<para>
@ -871,6 +940,17 @@ hibernate.cache.region.factory_class=
for a description of the standard stacks.
</para>
</listitem>
<listitem>
<para>
The configurations that use PESSIMISTIC locking use isolation level
READ_COMMITTED. There are also two other standard configurations
not shown in the table that use REPEATABLE_READ:
<literal>pessimistic-entity-repeatable</literal> and
<literal>pessimistic-shared-repeatable</literal>. In all other
respects those configurations are the same as the similarly named
non- "-repeatable" configurations shown in the table.
</para>
</listitem>
</itemizedlist>