DekGenius.com
[ Team LiB ] Previous Section Next Section

B.5 Concurrency Patterns

ACID Transaction Pattern

Goal

To perform multiple actions on a set of resources while ensuring that the underlying resources always remain in a correct state (Figure B-14).

Figure B-14. Classes in a managed transaction environment
figs/j2ee_ab14.gif

Participants

Business logic

Provides the application with its underlying constraints and process flow.

Transaction management layer

Provides code for coordinating the business logic and data access logic to ensure that all transactions meet a set of requirements.

Persistence layer

Responsible for storing data in persistent storage, usually (but not necessarily) a database.

Interactions

All business and data-access logic route any changes to data via a transaction manager object. The transaction manager acts as a gateway either to the persistence layer of the application or to the domain object model itself. It is responsible for ensuring that all permanent changes to the data underlying the application are atomic (treatable as a single unit rather than a set of individual changes), consistent (consistent with its business rules and constraints at the end of each transaction), isolated (do not interfere with other simultaneous transactions), and durable (changes made in the course of a successful transaction become part of the permanent state of the system).

Notes

In an EJB environment, the transaction manager is embedded within the application server. When using regular objects with a database, the database itself can assume some transaction management responsibilities, and the other patterns in this section, such as Lock Manager, can be used to fill in the gaps.

Lockable Object Pattern

Goal

Implement simple locking within a single JVM (Figure B-15).

Figure B-15. Lockable object
figs/j2ee_ab15.gif

Participants

Business delegate

Provides access to business logic.

Lockable object

Provides a data object that can be locked for exclusive use by a business delegate.

Interactions

When a business delegate needs to modify an object, it calls the object's lock( ) method. If a lock can be obtained, the business delegate updates the object and releases the lock.

Lock Manager Pattern

Goal

Provide a central point for managing lock information without requiring individual data objects to be locking-aware (Figure B-16 and Figure B-17).

Figure B-16. Lock manager
figs/j2ee_ab16.gif
Figure B-17. Offline lock manager
figs/j2ee_ab17.gif

Participants

Business delegate

Provides access to business logic.

DAO

Provides access to the persistence layer.

Lock manager

Coordinates access to resources for different objects.

Database (offline variant)

Provide a centralized location to store locking information for use by many clients or by a clustered application.

Interactions

When a business delegate or a DAO needs to lock a resource, it requests a lock on the object via a lock manager object. The lock manager takes a primary key and determines if the entity associated with the key is already locked. If it is not, it locks the resource on behalf of the user requesting the lock. When the user is done, he releases the lock.

The offline lock manager variant stores lock information "offline," in a database. This allows multiple JVMs to share locking information in a distributed environment.

Notes

As with pessimistic concurrency in general, applications must take care to ensure that locks are released, and ensure that abandoned locks are released after a timeout period.

Optimistic Concurrency Pattern

Goal

To allow multiple users safe access to shared resources in environments in which there is minimal risk that two users will simultaneously edit the same data (Figure B-18).

Figure B-18. Optimistic concurrency sequence
figs/j2ee_ab18.gif

Participants

Presentation tier

Presents the end user with an interface to the application.

Business delegate

Provides access to business logic.

DAO

Provides access to the persistence layer.

Interactions

A user interacting with the presentation tier requests data to edit. The user performs edits and requests that the edits be saved by the system. The system checks to see if the data has been changed externally since the user began the edit process (possibly by retrieving the data a second time and comparing). If the data was changed externally, the system provides the user with an error message. If the data has not been changed, the system applies the user's changes.

Notes

Optimistic concurrency works best in situations where there is little opportunity for collision between users, because when collision occurs, one user will have to rekey their data.

Pessimistic Concurrency Pattern

Goal

Allow multiple users to access shared resources in an environment where the possibility of collision is high, without forcing users to discard work (Figure B-19).

Figure B-19. Pessimistic concurrency pattern
figs/j2ee_ab19.gif

Participants

Presentation tier

Provides a user interface to the end user.

Business delegate

Provides access to business logic.

Lock manager

Coordinates resource locking across multiple objects.

DAO

Provides access to the persistence layer.

Interactions

A client connects to the presentation tier and initiates a data edit session. The presentation tier contacts a business delegate to retrieve the data the user wants to edit. The business delegate contacts a lock manager object and requests a lock on the specific data the user wants to edit. If a lock is unavailable, the business delegate returns a message to the presentation tier. If a lock is available, the business delegate retrieves the data from a DAO and passes it back to the presentation tier. The user makes their edits and submits them back to the presentation tier. The presentation tier submits the changes to the business delegate, which submits them to the DAO. The DAO verifies the lock and writes the changes to the persistence layer. The business delegate then releases the lock.

Notes

Pessimistic concurrency prevents users from having their edits rejected by the system due to concurrent changes. However, it can be much more difficult to implement properly: if locks are not released properly, the entire system can gradually become unavailable.

Transactional Context Pattern

Goal

Allow multiple objects to participate in a single transaction without imposing a large amount of overhead on the programmer (Figure B-20).

Figure B-20. Business delegate and DAOs using the Transactional Context pattern
figs/j2ee_ab20.gif

Participants

Business delegates

Provide access to business logic.

Data access objects

Provide access to persistence resources, such as a database.

Transactional context object

Coordinates activities between business delegates, data access objects, and the underlying database.

Transaction-aware database

Provides system level transaction support.

Interactions

When an application needs to begin a transaction, it obtains a transactional context object from the system and initiates a transaction with the context. All classes with access to the context use it to access transaction-sensitive resources, such as database connections, allowing multiple objects to share a single database transaction.

Notes

This pattern is particularly useful when building servlet-based applications with business delegate and DAO objects. You can associate a transactional context with each request, allowing business delegates to easily manage a transaction involving multiple DAOs and even multiple business delegates. See Chapter 10 for extensive examples.

Version Number Pattern

Goal

Provide a simple way to detect when an object has changed (Figure B-21).

Figure B-21. Versioned object
figs/j2ee_ab21.gif

Participants

Versioned object

Provides an object representation of data subject to change control, and tracks the changes that occur to the data.

Business tier code

Uses the version number to determine when to persist the versioned object.

Interactions

When an application modifies a property on a versioned object, a version number associated with the object is incremented. Other code can record this version number and use the information to resolve concurrency problems, such as change detection in an optimistic concurrency implementation.

Notes

See related patterns IsDirty and Optimistic Concurrency.

    [ Team LiB ] Previous Section Next Section