[ Team LiB ] |
B.5 Concurrency Patterns
GoalTo 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 environmentParticipants
InteractionsAll 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). NotesIn 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.
GoalImplement simple locking within a single JVM (Figure B-15). Figure B-15. Lockable objectParticipants
InteractionsWhen 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.
GoalProvide 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 managerFigure B-17. Offline lock managerParticipants
InteractionsWhen 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. NotesAs 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.
GoalTo 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 sequenceParticipants
InteractionsA 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. NotesOptimistic 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.
GoalAllow 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 patternParticipants
InteractionsA 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. NotesPessimistic 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.
GoalAllow 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 patternParticipants
InteractionsWhen 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. NotesThis 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.
GoalProvide a simple way to detect when an object has changed (Figure B-21). Figure B-21. Versioned objectParticipants
InteractionsWhen 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. NotesSee related patterns IsDirty and Optimistic Concurrency. |
[ Team LiB ] |