Download Transaction Commit Options - Entity beans in the EJB container of BES

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Commitment ordering wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Clusterpoint wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Database model wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Object-relational impedance mismatch wikipedia , lookup

Serializability wikipedia , lookup

Concurrency control wikipedia , lookup

Transcript
Transaction
Commit Options
EJB™
Entity beans in the
container of
Borland® Enterprise Server
by Jonathan Weedon, Architect: Borland® VisiBroker®
and Borland® AppServer,™ and
Krishnan Subramanian, Enterprise Consultant
Introduction
This paper provides an overview of the transaction commit
options defined in the Enterprise JavaBeans™ (EJB™)
specification and how the EJB container in Borland® Enterprise
Server, AppServer Edition handles those options. The various
transaction commit options defined in the EJB specification are
applicable to entity beans only. This paper enumerates the
behavior and performance of entity beans running within the
EJB container of Borland Enterprise Server when using each of
the transaction commit options.
Entity beans reviewed
Borland Software Corporation
Entity beans provide an object view of data. The data is usually
June 2002
stored in a relational database, although it is also possible for an
entity bean to provide an object view of an existing (legacy)
application. To maintain data integrity, entity beans usually are
accessed in the scope of a transaction.
Contents
The EJB container of the Borland Enterprise Server manages
Introduction
1
Instance life cycle
2
Transaction commit options
4
Conclusion
9
the synchronization among concurrent invocations from
multiple client threads; the bean provider need not be concerned
with this fact. To support concurrency, the EJB container
creates as many instances of entity beans as there are
simultaneous transactions; this is one of the strengths of EJB
container implementation (for both EJB™ 1.1 and EJB™ 2.0) by
Borland. Some vendors serialize access to a single entity bean
instance, limiting scalability.
Borland® Enterprise Server
EJB container
Instance life cycle
The EJB 1.1 and EJB 2.0 specifications define three states for an
entity bean instance:
Single entity
bean instance
Clients
¾
Does not exist
¾
Pooled state
¾
Ready state
Figure 1: Serializing access to an entity bean.
In the following sections, we discuss each of these states and
As the preceding figure shows, some vendors attempt to solve
how the container moves entity beans among the various states.
the problem of synchronizing concurrent client access to entity
beans by serializing access to a single entity bean instance.
Does not exist
However, this solution is not scalable since a single entity bean
The “does not exist” state is not particularly interesting, as this is
instance cannot efficiently service requests when the number of
the state an entity bean is in before it is instantiated. This state is
clients increases. Note also that this solution is imperfect when
analogous to nothingness.
the EJB container is clustered.
Pooled state
The “pooled” state is where an entity bean’s life starts, when the
EJB container of
Borland Enterprise Server
EJB container instantiates the entity bean. After creating an
instance, the container then invokes the
setEntityContext(EntityContext) method to pass the
created instance a reference to the EntityContext interface.
The pooled state is where an entity bean instance is not
associated with a primary key.
Clients
DOES NOT
EXIST
Figure 2: How the EJB container of Borland Enterprise Server handles
simultaneous client requests.
ejbFind…(args)
ejbSelect…(args)*
ejbHome…(args)*
* EJB 2.0 only
As the above figure shows, the EJB container of Borland
Enterprise Server creates as many instances of entity beans as
there are simultaneous transactions. That is, these instances run
Step 1: newInstance()
Step 2: setEntityContext(ec)
POOLED
in parallel, servicing client requests more efficiently.
Figure 3: Pooled state.
2
Borland® Enterprise Server
Beans in this state can be used to execute methods in the home
POOLED
interface. Note that a call to methods in the home interface will
result in the instance remaining in the pooled state. The property
ejbActivate()
ejb.maxBeansInPool controls the number of bean instances
in this state, with a default setting of 1000. When the container
CACHED
WITHOUT STATE
starts up (or is restarted), there are no instances in the pooled
state. That is, the pool is filled lazily in the Borland Enterprise
Server. The number of entity bean instances in this state
Figure 4: Cached without state.
increases as required, depending on access by various clients.
Ready state
Transactional state
An entity bean is in the “ready” state when the instance is
The “transactional” state is where entity bean instances actually
associated with a specific object identity. In other words, the
execute business methods. Beans in this state are always
given entity bean instance is associated with a primary key. Let’s
associated with a transaction and typically return to the cached
extend this aspect of the EJB specification with our own
or pooled state at the end of the transaction.
visualization for the sake of clarity.
POOLED
ejbPassivate()
ready state:
¾
Cached state
¾
Transactional state
ejbActivate()
Assume there are two sub-classifications of bean instances in the
CACHED
WITHOUT STATE
Cached state
The cached state is where an entity bean instance is associated
ejbLoad()
TRANSACTIONAL
ejbStore()
Figure 5: Transactional state.
with a primary key. Depending on the transaction commit
option (discussed in the next section), the bean instance might
As seen in the figure above, the entity bean instance in the
also be associated with state (state means the persisted fields
“Cached without state” knows only about its primary key and
other than the primary key). The size of this cache is governed
not the values of its persisted fields. The value of these persisted
by the ejb.maxBeansInCache property, with a default setting
fields needs to be synchronized with those in the database; this is
of 1000. As in the pooled state, the number of entity bean
accomplished via a call to the ejbLoad() method. Once the
instances in the cached state is filled lazily as new primary keys
ejbLoad() is performed, the entity bean will have all the
are encountered. If the application uses a small table or a few
persisted fields in sync with those in the database (for that
rows from a given table, often far fewer than 1000 beans are
transaction) and can then execute business methods.
typically in use. For performance reasons, you may want to
increase the size of this cache since it increases the likelihood of
a cache hit (i.e., the given item could be retrieved from the
cache). Caveat: Too many entity bean instances in memory may
start to impact garbage collection, although this depends on the
configuration of the Java™ Virtual Machine (JVM™) and
hardware.
3
Borland® Enterprise Server
¾
POOLED
ejbPassivate(): This disassociates the bean from
its primary key, i.e., the bean instance returns to the
ejbPassivate()
ejbRemove()
ejbActivate()
pooled state.
POOLED
CACHED
WITHOUT STATE
ejbLoad()
TRANSACTIONAL
Step 1: ejbActivate()
Step 2: ejbLoad()
ejbStore()
business methods
ejbSelect…(args)*
* EJB 2.0 only
Step 4: ejbStore()
Step 5: ejbPassivate()
TRANSACTIONAL
Figure 6: Transactional state transitions.
Step 3: business method(s)
Transaction commit options
Figure 7: Option C—bean states.
There are three transaction commit options defined by the EJB
1.1 and EJB 2.0 specifications. These are commit options A, B,
Option B
and C. We start with option C, as it is the simplest behavior.
Option B is the default behavior of Borland Enterprise Server.
Here, bean instances are kept in the cache: the bean instances are
Option C
associated with a primary key, but the state of an entity bean’s
In option C, the cache is not used, that is, the property
persisted fields are not synchronized with the values in the
ejb.maxBeansInCache is ignored. Entity bean instances in
database. When a client invokes a business method, the EJB
this pool wait for something to do. If a call on the home
container checks its cache to see whether a corresponding bean
interface occurs, the entity bean executes against an instance
instance (identified by its primary key) exists. If so, then that
from this pool—which is in fact the behavior for all commit
cached instance is taken out and used. The ejbLoad() is
options. If a business method is invoked by a client, the
invoked on this cached instance to synchronize its state
following sequence of calls is made:
¾
(persisted fields) with those in the database.
ejbActivate(): This associates the bean instance
with a primary key.
¾
If the cache does not contain an instance associated with that
ejbLoad(): This associates the bean instance with the
primary key (either because the bean associated with that
state in the database i.e., the persisted fields in the
primary key has not been accessed previously or because some
entity bean are synchronized with those in the database.
other concurrent transaction has already taken the bean instance
Following the above two calls, the business methods are
out of the cache for its own use), then a bean instance is
executed in the scope of that transaction. When the transaction
transitioned out of the pooled state. In this case, the
ends (i.e., the transaction commits), the following sequence of
ejbActivate() is called to first associate the bean instance
calls are made:
¾
with a primary key, then followed by a call to ejbLoad() to
ejbStore(): This updates the database with the
synchronize the state of the entity bean with the state in the
changed values (if any) of the entity bean instance’s
database.
persisted fields.
4
Borland® Enterprise Server
As indicated by the figure above, once the entity bean in the
EJB container in Borland Enterprise Server
transaction ready state executes the business method(s), the
business method
container calls the ejbStore() and sends the bean back to the
PK=2 PK=5
Client
cache. It is possible that the bean instance enters the pooled
state after ejbStore() is called by calling ejbPassivate():
PK=8
this would happen if there already existed an entity in the cache
Cached
without state
Pooled state
for the given primary key.
Figure 8: Option B—client invokes business method
Option A
In the preceding figure, assume that the cache of the EJB
Option A provides optimized data access in cases where the EJB
container holds three instances of an entity bean, each with its
container has exclusive access to the database or where the
own primary key (the entity bean instances only know their
underlying data is either read only, or insert only. In other words,
primary keys). Assume that there are a number of bean instances
this option provides optimized data access in cases where
in the pooled state; these instances are not associated with any
existing rows in the database are not modified (though new ones
primary key.
could be inserted over time).
The following sequences of events occur in the EJB container of
In this case, the container uses a cache to hold the beans
Borland Enterprise Server when a client invokes a business
associated with a primary key. However, when Option A is used,
method on an Option B entity bean:
the entity beans are also associated with the state in the database.
In other words, the entity bean instance not only holds the
Does the entity bean referenced by
the client exist in the cache?
Yes, so get it out
of the cache
primary key field but also the values for all its persisted fields.
The handling of Option A by the Borland Enterprise Server is
very similar to the handling of entity beans using Option B. As
No, so get any instance
out of the pool
with Option B, when a client invokes a business method, the
EJB container first looks in the cache. If the entity bean instance
CACHED
WITHOUT
STATE
ejbLoad()
ejbActivate()
matching that primary key identity is found, the instance is taken
out from the cache and used. It should be noted that if the cache
POOLED
does contain the required entity bean instance, then a call to the
ejbPassivate()
ejbLoad() can be avoided because the state of the bean is
known to be consistent with the state from the last committed
ejbStore()
transaction.
TRANSACTIONAL
If the entity bean instance cannot be found in the cache, then
the EJB container gets an instance from the pool and calls the
execute business
method(s)
ejbLoad() to load the state from the database.
Figure 9: Option B—handling request internally by the container.
5
Borland® Enterprise Server
EJB container in Borland Enterprise Server
Combining the facts that (a) Option A can suppress
reads from the database (when that instance is present
business method
in the cache), and (b) the difference detection engine in
PK=2 PK=5
Client
the Borland implementation for CMP eliminates writes
to the database (i.e., eliminates updates in the
PK=8
Cached with
state
ejbStore() method) when no fields were modified,
Pooled state
demonstrates how our product provides entity bean
support with no database access. In other words, a
Figure 10: Option A—client invokes business method.
pure middle-tier data cache!
In the figure above, the cache contains three entity bean
instances. These instances are associated with their primary key
and with their state in the database. The pooled state contains
Putting Option A beans back into the cache can be a bit tricky.
entity bean instances that are not associated with any particular
The Borland Enterprise Server uses a “first out, last in”
primary key. The following sequences of events occur in the EJB
algorithm—the first transaction that wants to use the bean
container of Borland Enterprise Server when a client invokes a
instance gets it from the cache. If a subsequent transaction(s)
business method on an Option A entity bean:
requests the same bean instance from the cache, we get a cache
miss because the first transaction has already removed the bean
Does the entity bean referenced by
the client exist in the cache?
Yes, so get it out
of the cache
instance from the cache. The cache miss implies that a bean
instance has to be retrieved from the pool, then is followed by a
call to ejbActivate() (to associate the instance with its
No, so get any instance
out of the pool
primary key) and more importantly an ejbLoad(). That is, only
the first transaction needing a particular bean can avoid an
ejbLoad(). Concurrent transactions must get that bean from
TRANSACTIONAL
the database.
POOLED
Subsequently, the last transaction to complete successfully puts
execute business
method(s)
the bean back in the cache. The implementation of Transaction
Step 1: ejbActivate()
Step 2: ejbLoad()
Commit Option A by Borland provides the benefits of exclusive
database access without the need to serialize entity bean access.
Figure 11: Option A—handling request internally by the container.
Serializing entity bean access implies that a single entity bean
instance (in the ready state) services client requests in a serial
manner. As mentioned in the beginning of this paper, this is not
a scalable option.
The following figure shows how the EJB container handles
Option A entity beans accessed by concurrent transactions,
labeled T1 and T2. The contents of the cache and the state of
the entity bean are shown. Also illustrated is the way the last
transaction to complete successfully puts the state associated
with that entity bean instance back in the cache.
6
Borland® Enterprise Server
T2
Cache
bean state
(in cache)
get bean: 2
PK = 2
PK = 2
State = x
T1
get bean: 2
¾
Pooled
¾
Cached (may be with or without state, i.e., with state
when Option A is used and without state when Option
B is used)
¾
Transactional state
In the following section, we discuss an interesting feature of
modify state (x)
to y
commit
transaction
Does not exist
empty
not found, get
from DB
modify state
(x) to z
¾
entity bean support that limits the number of entity bean
instances in a transaction.
PK = 2
PK = 2
State = y
The ejb.maxBeansInPools and the
ejb.maxBeansInCache properties control the pooled state
and cached state, as mentioned above. The flag
commit
transaction
PK = 2
PK = 2
State = z
ejb.maxBeansInTransactions governs the number of
bean instances possible in the transactional state. Typically, you
would use this flag when you run a batch-style operation, such as
if you were running through a large number of entity beans in a
single transaction. For reasons of performance and isolation, you
might want to run such batch-style operations in a single
Figure 12: Option A—writing back to the cache from multiple
transaction. Until now, we have seen cases where beans were
transactions.
returned to the cache or pool only upon transaction completion.
The most common concern when running batch transactions
The EJB 1.1 and 2.0 specifications actually suggest that
that access a large number of entity beans is the resource usage
Option A can only be used by serializing access to a
in terms of memory increasing substantially.
single entity bean instance. The fact that the Borland
Enterprise Server, AppServer Edition provides
The property ejb.maxBeansInTransactions controls the
concurrent access to Option A beans (i.e. without the
number of entity bean instances in the transactional state that are
need for serializing access) correctly is cool!
actually allocated to active transactions. The default size is 500,
which is half the default size of the bean instances in the
So far we have discussed only the settings in the EJB container
pool/cache. So if the default sizes of the pool/cache were
of the AppServer Edition to limit the number of bean instances
changed, then the ejb.maxBeansInTransactions value
in the pooled state or cached state. As we have discussed, the
should probably be adjusted accordingly.
EJB specification mentions the three states possible for an entity
bean. The last state, the ready state, is split into two: cached state
The way this property works is as follows: when a transaction
and transactional state. So, in effect, there are four states
accesses an entity bean, the entity bean instance is usually
possible from our perspective:
allocated to that given transaction. However, before the entity
bean instance is allocated to that transaction, a check is made to
see whether the number of entity bean instances in the
transactional state exceeds the
7
Borland® Enterprise Server
ejb.maxBeansInTransactions value. If so, then other
For example, your session façade could initiate a transaction and
beans in the current transaction are moved to the cache/pool by
call an entity bean’s finder method that returned 100,000 rows.
calling ejbStore() or ejbPassivate(), depending on the
The session bean would then iterate through the finder
commit option selected. In effect, the ejbStore() or
collection, get the data from the entity bean, put these in some
ejbPassivate() is not called at the end of a transaction but
kind of a data structure, and return them to the client. Instead of
rather when the number of entity bean instances exceeds the
instantiating 100,000 objects (as many vendors do) the EJB
limit set by the ejb.maxBeansInTransactions property.
container instantiates only 500 objects (or whatever the size of
the ejb.maxBeansInTransactions is set to be) and caches
As the following figure shows, the elements that are light in
a subset of the total rows (the subset has a default of 1000
color represent the number of beans in the cached state (the
instances associated with the primary key, not the state).
default limit is 1000). The elements within the smaller window,
Instances are moved from the transaction state to the cached
in a darker shade, represent the number of bean instances in the
state, based on the Least Recently Used (LRU) algorithm.
transactional state. The number of bean instances in the
transactional state (the size of the smaller window) is governed
Large-scale performance tests have shown that this
by the ejb.maxBeansInTransactions property. In effect,
implementation provides a good space/time tradeoff. The
the EJB container dynamically “slides” the window of active
strategy is extremely effective at keeping batch-style operations
beans—as well as the window of cached beans—across the total
running in a controlled amount of memory without impacting
items in the data set.
the performance of other types of transactions that do not
"window" size governed by
ejb.maxBeansInCache value
"window" size governed by
ejb.maxBeansInTransactions value
In the CMP 1.1 engineof Borland Enterprise Server, we read all
the results from the JDBC® ResultSet at one time. That is, if
there were 100,000 records, we would read all 100,000 records
from the ResultSet immediately, but only instantiate as many
entity bean instances as there are set by the
ejb.maxBeansInPool property.
In the 5.x version of Borland Enterprise Server, which supports
the EJB 2.0 specification, we lazy-load from the ResultSet
Bean instances in
cached state.
Bean instances in transactional state
Total rows (e.g. result of a finder method)
exceed their transactional limits.
also. That is, we do not scroll through the ResultSet returned
by a SQL query when the finder executes. Rather, we scroll
through the ResultSet as and when the caller requests more
items.
Figure 13: Use of ejb.maxBeansInTransactions property.
8
Borland® Enterprise Server
Conclusion
So, what should you do to optimize your application? The first
Benchmarking clients typically access entities at random, in
question is to determine whether your EJB container can use
which case Option C might be preferred. And, of course, if you
Option A. The answer would be based on whether it is possible
have batch operations, you might want to consider the impact of
to have exclusive access to the database or whether certain tables
ejb.maxBeansInTrasanctions property.
(or beans) are either read only or insert only.
The Java™ ECperf™ benchmarking exercise conducted on the
The next consideration is to determine which kinds of memory
AppServer Edition has demonstrated that the default entity bean
constraints you might have in your deployment environment. If
configuration in the EJB container of Borland Enterprise Server
your deployment environment provides only a small amount of
is quite effective. Borland used the default configuration for all
memory, you might want to reduce the size of the cache and
entity beans in the ECperf test and found excellent results. We
pool, likewise reducing the number of beans in transactions.
did try changing a number of variables, including trying Option
Option C will consume less memory than Option B due to the
C instead of Option B (Option A is disallowed by ECperf run
fact there is only a pool and no cache. Note that caches are
rules), and varying the pool/cache sizes.
effective only if there is a high likelihood of a cache hit (i.e., an
item can be found in the cache). So, if your application exhibits
In all cases, we found that such changes either hurt performance
locality of reference as do most real world applications, then
or had no measurable impact. So, unless there are significant
Option B is preferable to Option C.
memory constraints or unless Option A can be used, it is
recommended that the default configuration be used as a starting
point for performance optimization.
Made in Borland® Copyright © 2002 Borland Software Corporation. All rights reserved. All
Borland brand and product names are trademarks or registered trademarks of Borland Software
Corporation in the United States and other countries. Java and all Java-based marks are
trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All
other marks are the property of their respective owners. Corporate Headquarters: 100 Enterprise
Way, Scotts Valley, CA 95066-3249 • 831-431-1000 • www.borland.com • Offices in: Australia,
Brazil, Canada, China, Czech Republic, France, Germany, Hong Kong, Hungary, India, Ireland,
Italy, Japan, Korea, the Netherlands, New Zealand, Russia, Singapore, Spain, Sweden, Taiwan, the
United Kingdom, and the United States. • 12691
100 Enterprise Way
Scotts Valley, CA 95066-3249
www.borland.com | 831-431-1000
9