Version 8

    cmp2.x jdbc2 pm

     

    This is a name of a default entity bean container configuration which uses CMP2.x compatible JDBC based persistence manager in the org.jboss.ejb.plugins.cmp.jdbc2 package. The development of this persistence manager was driven by performance tests.

    The reasons to write a new persistence manager instead of optimizing the existing one were:

    • we needed a better performance which could not be achieved with the existing persistence manager which is quite sophisticated and performing major rafactorings is not easy w/o breaking the documented functionality and testsuites;

    • we needed to address major architectural issues in caching and locking;

    • we needed a more efficient persistent data synchronization mechanism.

     

    Caching

     

    Previously, you had to choose between a (cross-transactional) cache (i.e. commit option A) with pessimistic locking in EJB container and no cache with no locking in EJB container (e.g. Instance Per Transaction container configuration with no or optimistic locking). These are two extreme cases. The new persistence manager addresses this issue by using a two level cache.

    Entity instance cache is a per transaction cache. (In fact, the implementation is one that is used in the Instance Per Transaction container configuration.) Plus, there is a global (cross-transaction) cache of row data (think of it like a cache of database rows).

    It means that each transaction gets its own copy of the entity EJB instance (from the instance cache) associated with the same persistent data (in the row cache). Concurrent transactions can work on the same persistent data simulteniously. To prevent concurrent modifications leading to inconsistency in the database it is recommended to use optimistic locking.

     

    Locking

     

    Since each transaction gets its own copy of entity EJB instances, there is no need for pessimistic locking in the EJB container. But we use a global cache. And operations like put into, remove from the cache, etc require pessimistic locking on the cache level. It is still better than holding a pessimistic lock on the instance for the duration of the transaction though. Plus, there are configuration options to reduce lock contention on the cache.

     

    Cache configuration

     

    Let's look at the default container-cache-conf element for this container:

          <container-cache-conf>
             <cache-policy-conf>
                <min-capacity>500</min-capacity>
                <max-capacity>10000</max-capacity>
                <!-- time-based eviction
                <overager-period>300</overager-period>
                <max-bean-age>600</max-bean-age> -->
             </cache-policy-conf>
             <cache-policy-conf-other>
                <partitions>10</partitions>
                <!-- uncomment to use JDBC java.sql.Statement.executeBatch()
                <batch-commit-strategy></batch-commit-strategy>
                -->
             </cache-policy-conf-other>
          </container-cache-conf>
    

     

    min-capacity

    The initial capacity of the cache

     

    max-capacity

    The maximum capacity of the cache. max-capacity is used by the size-based eviction policy, i.e. if the maximum capacity is exceeded, the data is evicted with Least Recently Used policy.

     

    overager-period/max-bean-age

    These two settings if used must be used together. They define time-based eviction policy. Support for these options in 'cmp2.x jdbc2 pm' was added in jboss-3.2.8RC1 and jboss-4.0.4beta. The meaning of these options is exactly the same as in the traditional 'Standard CMP 2.x EntityBean'.

     

    partitions

    To reduce lock contention, the cache is devided into partitions. When we need to put or remove an instance from the cache we lock only the partition the instance belongs to, not the whole cache leaving other partitions available for concurrent transactions.

     

    batch-commit-strategy

    If present the synchronization will use java.sql.PreparedStatement.executeBatch().

     

    Each row cache is an MBean.

     

    Data synchronization

     

    With this persistence manager the synchronization occurs only at commit time and query execution except for findByPrimaryKey. When an instance is created the corresponding INSERT statement is issued also at commit time unless insert-after-ejb-post-create is true. In the former case INSERT statement will be issued right after ejbPostCreate callback on the instance.

     

    Referenced by: