incorporate a useful rant about caching in javadoc

This commit is contained in:
Gavin 2022-12-30 13:24:07 +01:00
parent 31f11f4e3c
commit 61f71030ff
2 changed files with 59 additions and 19 deletions

View File

@ -131,12 +131,46 @@
* These two approaches cannot be used together. A {@code UserType} always takes precedence
* over the compositional approach.
* <p>
* Please see the <em>User Guide</em> or the package {@link org.hibernate.type} for further
* discussion. The packages {@link org.hibernate.type.descriptor.java} and
* The packages {@link org.hibernate.type.descriptor.java} and
* {@link org.hibernate.type.descriptor.jdbc} contain the built-in implementations of
* {@code JavaType} and {@code JdbcType}, respectively.
* <p>
* Please see the <em>User Guide</em> or the package {@link org.hibernate.type} for further
* discussion.
*
* <h3 id="basic-value-mapping">Dialect-specific native SQL</h3>
* <h3 id="second-level-cache">Second level cache</h3>
*
* When we make a decision to store an entity in the second-level cache, we must decide
* much more than just whether "to cache or not to cache". Among other considerations:
* <ul>
* <li>we must assign cache management policies like an expiry timeout, whether to use
* FIFO-based eviction, whether cached items may be serialized to disk, and
* <li>we must also take great care in specifying how
* {@linkplain org.hibernate.annotations.CacheConcurrencyStrategy concurrent access}
* to cached items is managed.
* </ul>
* <p>
* In a multi-user system, these policies always depend quite sensitively on the nature
* of the given entity type, and cannot reasonably be fixed at a more global level.
* <p>
* With all the above considerations in mind, we strongly recommend the use of the
* Hibernate-defined annotation {@link org.hibernate.annotations.Cache} to assign
* entities to the second-level cache.
* <p>
* The JPA-defined {@link jakarta.persistence.Cacheable} annotation is almost useless
* to us, since:
* <ul>
* <li>it provides no way to specify any information about the nature of the <em>how</em>
* cached entity and how its cache should be managed, and
* <li>it may not be used to annotate associations.
* </ul>
* <p>
* As an aside, the {@link jakarta.persistence.SharedCacheMode} enumeration is even worse:
* its only sensible values are {@code NONE} and {@code ENABLE_SELECTIVE}. The options
* {@code ALL} and {@code DISABLE_SELECTIVE} fit extremely poorly with the practices
* advocated above.
*
* <h3 id="dialect-specific-sql">Dialect-specific native SQL</h3>
*
* Many annotations in this package allow the specification of native SQL expressions or
* even complete statements. For example:

View File

@ -8,36 +8,42 @@
/**
* Defines contracts for transactional and concurrent access to cached
* {@linkplain org.hibernate.cache.spi.access.EntityDataAccess entity} and
* {@linkplain org.hibernate.cache.spi.access.CollectionDataAccess collection} data. Transactions pass in a
* timestamp indicating transaction start time which is then used to protect against concurrent access (exactly how
* that occurs is based on the actual access-strategy impl used). Two different implementation patterns are provided
* for:
* {@linkplain org.hibernate.cache.spi.access.CollectionDataAccess collection} data.
* <p>
* Transactions pass in a timestamp indicating transaction start time which is then used to protect against concurrent
* access. Exactly how that happens is based on the actual access-strategy implementation used.
* <p>
* Two different implementation patterns are provided for:
* <ul>
* <li>
* A transaction-aware cache implementation might be wrapped by a <i>synchronous</i> access strategy,
* A transaction-aware cache implementation might be wrapped by a <em>synchronous</em> access strategy,
* where updates to the cache are written to the cache inside the transaction.
* </li>
* <li>
* A non-transaction-aware cache would be wrapped by an <i>asynchronous</i> access strategy, where items
* A non-transaction-aware cache would be wrapped by an <em>asynchronous</em> access strategy, where items
* are merely "soft locked" during the transaction and then updated during the "after transaction completion"
* phase; the soft lock is not an actual lock on the database row - only upon the cached representation of the
* item.
* phase. The soft lock is not an actual lock on the database row, it only prevents access to the cached
* representation of the item.
* </li>
* </ul>
* <p>
* The <i>asynchronous</i> access strategies are:
* The <em>asynchronous</em> access strategies are:
* {@linkplain org.hibernate.cache.spi.access.AccessType#READ_ONLY read-only},
* {@linkplain org.hibernate.cache.spi.access.AccessType#READ_WRITE read-write} and
* {@linkplain org.hibernate.cache.spi.access.AccessType#NONSTRICT_READ_WRITE nonstrict-read-write}.
* The only <i>synchronous</i> access strategy is
* The only <em>synchronous</em> access strategy is
* {@linkplain org.hibernate.cache.spi.access.AccessType#TRANSACTIONAL transactional}.
* <p>
* Note that, for an <i>asynchronous</i> cache, cache invalidation must be a two-step process (lock to unlock or
* lock to afterUpdate), since this is the only way to guarantee consistency with the database for a non-transactional
* cache implementation. For a <i>synchronous</i> cache, cache invalidation is a single step process (evict or update).
* Hence, these contracts ({@link org.hibernate.cache.spi.access.EntityDataAccess} and
* {@link org.hibernate.cache.spi.access.CollectionDataAccess}) define a three-step process to cater for both
* models (see the individual contracts for details).
* Note that:
* <ul>
* <li>for an <em>asynchronous</em> cache, cache invalidation must be a two-step process ("lock" then "unlock", or
* "lock" then "after update"), since this is the only way to guarantee consistency with the database for a
* non-transactional cache implementation, but
* <li>for a <em>synchronous</em> cache, cache invalidation may be performed in a single operation ("evict" or "update").
* </ul>
* Hence, the contracts {@link org.hibernate.cache.spi.access.EntityDataAccess} and
* {@link org.hibernate.cache.spi.access.CollectionDataAccess} define a three-step process to allow for both models
* (see the individual contracts for details).
* <p>
* Note that query result caching does not go through an access strategy; those caches are managed directly against
* the underlying {@link org.hibernate.cache.spi.QueryResultsRegion}.