The One-PM-per-Update Design


In the one-pm-per-update design, one persistence manager is shared for all requests that read persistent objects. At the same time, each request that modifies persistent objects creates and closes a persistence manager for the update.

In most Web applications, the number of HTTP requests that modify information is much less than the number of requests that read, but do not modify, information. Most interactive use of persistent data, regardless of the persistence mechanisms or the deployment architecture, share this characteristic. Like the other designs, the one-pm-per-update design benefits from any level-two cache supplied by the implementation, but when the JDO implementation does not provide a level-two cache, the shared read-only persistence manager offers the maximum performance benefit from the JDO-defined cache.

If the design avoids making persistent objects transient on each request, then this design also minimizes garbage collection since the shared read-only persistence manager will reuse the same persistent objects as long as the persistence manager remains open.

In this design, the NontransactionalRead property of the read-only persistence manager is turned on, since this persistence manager does not use transactions at all. The Multithreaded property must also be turned on, since multiple threads will be sharing the same persistence manager. Turning on the Multithreaded property may decrease the performance of the persistence manager, as it may now turn on some synchronization and turn off some optimization to accommodate the application's multithreaded use. At the same time, there can be some queuing of activities in the persistence manager. For example, while the database connection is being used to run a query for one thread, other threads seeking to execute queries may be held up.

The best approach for scaling up is to store the service that uses the shared persistence manager in an instance field of the servlet where it will be shared by all threads running in the servlet instance. The service that uses the shared persistence manager is initialized in the servlet's init method. When the container notices an increased load, it will likely create another instance of the servlet, which initializes its own service using a different read-only persistence manager that is shared among the requests processed by the new servlet instance.

The transactional issues for the one-pm-per-update design are the same as for the one-pm-per-request design. Since the read occurs in one persistence manager and the write occurs in another, there is no opportunity for JDO to provide a shared transactional context. To provide concurrency control, the application must roll its own version control, such as the SupportsVersion interface described earlier.

Implementing the one-pm-per-update design can be surprisingly complex. The complexity revolves around managing the cache of persistent objects in one or more shared read-only persistence managers. When an update request modifies persistent objects in its own persistence manager, the persistent objects in all of the read-only persistence managers that refer to the same database object must be reloaded with the new state. Otherwise, the read-only persistence managers become quickly outdated. Likewise, the read-only persistence managers must reload the appropriate persistent objects when optimistic concurrency failures occur in the write transactions. Otherwise, they continue to serve outdated information.

Writing a cache synchronization scheme is not a simple task because there may be multiple shared read-only persistence managers in multiple, clustered servlet containers. Instead of writing cache synchronization code, the application's best option is to use a JDO implementation that provides for cache synchronization. Although cache synchronization is not defined by JDO, some implementations provide them as a value-added feature.

If the JDO implementation or the application provides a way to keep the objects in the read-only persistence managers up-to-date, then the shared read-only persistence manager can be kept open for the life of the servlet. In this case, the servlet closes its read-only persistence manager in its destroy method, which the servlet container calls just prior to removing the servlet from service.

Since any JDO implementation that offers cache synchronization across persistence managers is very likely to offer a level-two cache of persistent state, the benefit of using the one-pm-per-update design over the one-pm-per-request design comes down to the value of continuing to use the same persistent objects for all reads rather than creating new persistent objects on each request that soon become garbage. For this reason, the one-pm-per-update design promises some improvement in performance and scalability over the one-pm-per-request design.

To realize a performance benefit with the one-pm-per-update design, the Web application must avoid storing persistent objects in the session object. Since the container serializes the session when the container comes under load, the managed application data objects become unmanaged objects. As a result, they soon become garbage and thereby negate the expected benefit of the design at precisely the point when the benefit is needed.

An example of the one-pm-per-update design is not presented in this book because the cache synchronization on which it depends is most economically viewed as a feature that the JDO vendor, rather than the application, should supply.




Using and Understanding Java Data Objects
Using and Understanding Java Data Objects
ISBN: 1590590430
EAN: 2147483647
Year: 2005
Pages: 156
Authors: David Ezzio

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net