J2EE Blueprints Design Pattern
Bimodal Data Access

 name

Bimodal Data Access

 abstract

Under certain conditions, allows designer to trade off data consistency for access efficiency. JDBC provides read-only, potentially dirty reads of lists of objects, bypassing the functionality, and the overhead, of Entity enterprise beans. At the same time, Entity enterprise beans can still be used for transactional access to enterprise data. Which mechanism to select depends on the requirements of the application operation.

 intent

Quickly access read-only lists of objects, while maintaining consistent, transactional access to individual objects

 category

Object Behavioral

 motivation

Sometimes it's more important that a list of objects be accessed efficiently, than that the data in those objects be entirely up-to-date. For example, Java Pet Store Catalog items are displayed in a list, one page at a time (see the Paged List pattern.) When the user is simply browsing the catalog, it isn't crucial that the data in the database be entirely consistent with what is displayed on the screen.

At other times, data consistency and transaction control is of utmost importance. In the Java Pet Store, an Order being committed to the database must be consistent with the Catalog, or the ordering operation will fail.

The Bimodal Data Access pattern allows a design-time trade-off, sacrificing some data consistency for access efficiency. The application uses JDBC to directly access data used only for display, since in that case transactional support is unnecessary. But when the application needs to update the database transactionally, it uses enterprise beans.

In the Java Pet Store application, when a user is browsing the Catalog, the catalog items are being used only for display, and it's acceptable for some of the items to be bit stale. So, in the case of displaying pages of Catalog items, the Java Pet Store accesses the database directly through JDBC, instead of using enterprise beans. This provides much quicker access to the list of catalog items, but does not guarantee the future consistency of the data being displayed.

On the other hand, when the user creates a new Order (itself an Entity enterprise bean), the Java Pet Store represents the Catalog as a Session enterprise bean; that is, in the context of a transaction. Orders can only be placed against Catalog items that actually exist at the time the Order is created, so Order creation must be handled transactionally.

Java Pet Store reads the Catalog nontransactionally (via JDBC) to access lists of objects for display, but reads it transactionally (in an enterprise bean) when creating a new Order.


 applicability

Consider using Bimodal Data Access when:

  • making read-only access to a large list of data
  • consistency of the data in the list with the database is not critical

 structure

Figure 1. UML Diagram for Bimodal Data Access.

 participants

Client

  • displays read-only, non-transactional lists of data
  • updates individual data items transactionally
EnterpriseBean

  • reads or writes data
  • access data in the context of a transaction
DataAccessObject

  • provides transactional access to data

 collaborations

Client

  • reads lists nontransactionally with DataAccessObject
  • reads and updates data transactionally with EnterpriseBean
EnterpriseBean

  • provides Client with transactional access to database
  • uses enterprise bean functionality to implement transactional behavior
DataAccessObject

  • provides database access, transactionally or otherwise

 consequences

Consequences of BimodalDataAccess include:

  • Access efficiency and consistency appropriate to task. Where access efficiency is needed and consistency is secondary, data are accessed nontransactionally, avoiding the overhead of using enterprise beans. Likewise, transactions are still available when required.

  • API becomes more complex. Since persistent data are being accessed in two different ways, there are two separate APIs for accessing data. This makes the overall design less transparent.


 implementation-issues

  • Nontransactional reads are inappropriate for data that change often. Nontransactional reads are often used to build input to subsequent transactions. In the catalog example discussed above, the user creates orders based on catalog items obtained from a nontransactional read. This works properly because catalog information changes slowly. If the catalog were changing quickly, ordering would more likely fail, because the catalog items on which the orders depend could not reliably be found.


 sample-code

The Java Pet Store uses BimodalDataAccess pattern to access the Catalog when building and submitting an Order. In this example, the participants in the pattern are played by the following classes: