Tuesday 29 December 2009

Beyond Technologies: Domain Driven Design - Layered architecture

1. Introduction
In this post I sum up the most important concepts about Domain Driven Design.
I recommend you when you read this post not to think in technologies. Put away the technical knowledge and think from an upper level, from an architectural level.

2. Domain Driven Design elements
In future posts I will show my understanding about the following concepts:


  • Layered Architecture
  • Services
  • Entities
  • Value Objects
  • Aggregates
  • Repositories
  • Factories


3. Isolating the domain with a Layered architecture




The design and implementation of business logic constitute the domain layer. Isolating the domain implementation is a prerequisite for domain-driven design.




User interface

  • It shows information to the user
  • It interprets the user´s commands.

Application Layer

  • It defines the jobs the software is supposed to do.
  • The tasks are meaningful to the business or necessary for interaction with the application layers of other systems.
  • This layer is thin and does not contain business rules or knowledge
  • It coordinates tasks and delegates work to collaborations of domain objects in the next layer down.

Domain Layer or Model layer

  • It represents concepts of the business and the business rules.
  • The state that reflects the business situation is controlled and used here
  • This layer is the heart of the business software.

Infrastructure Layer

  • Provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI, and so on.
  • This infrastructure layer may also support the pattern of interactions between the four layers through an architectural framework.

Martin Fowler says: “If the architecture isolates the domain-related code in a way that allows a cohesive domain design loosely coupled to the rest of the system, then that architecture can probably support domain-driven design”.

4. References

Eric Evans 2004. Domain Driven Design. Tackling Complexity in the Heart of Software. Addison-Wesley.

Tuesday 8 December 2009

Locking in JPA 2.0

1.     Introduction
The JPA specification 2.0 assumes that the databases to which persistence units are mapped will be accessed by the implementation using read-committed isolation (or a vendor equivalent in which long-term read locks are not held).

2.     Optimistic Locking
Optimistic locking is a technique that is used to insure that updates (merge operation) to the database data corresponding to the state of an entity are made only when no intervening transaction has updated that data since the entity state was read.

Version Attributes
The Version field or property is used by the persistence provider to perform optimistic locking. An entity is automatically enabled for optimistic locking if it has a property or field mapped with a Version mapping.

@Entity
@Table(name = "ITEMS")
public class Item implements Serializable {
         
          @Id
          @Column(name = "ITEM_ID")
          private Long itemId;
         
@Column(name = "ITEM_NAME")
          private Long itemName;

          @Version
          @Column(name = "OPT_LOCK")
          private Integer version;
         
         
}

The persistence provider's implementation of the merge operation must examine the version attribute when an entity is being merged and throw an OptimisticLockException if it is discovered that the object being merged is a stale copy of the entity—i.e. that the entity has been updated since the entity became detached.

The version attribute is updated by the persistence provider runtime when the object is written to the database.

UPDATE ITEMS SET ITEM_NAME = 'Name test', OPT_LOCK = 2 WHERE ITEM_ID = 700 AND OPT_LOCK = 1

Optimistic lock modes
If transaction calls lock(entity, LockModeType.OPTIMISTIC) on a versioned object, the entity manager must ensure that neither dirty read nor non-repeatable read occurs.

If transaction calls lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT) on a versioned object, the entity manager must ensure that neither dirty read nor non-repeatable read occur and force an increment to the version at the end of the transaction, even if the entity is not modified.

Note: LockModeType.OPTIMISTIC is synonymous with LockModeType.READ and LockModeType. OPTIMISTIC_FORCE_INCREMENT is synonymous with LockModeType.WRITE.

3.     Pessimistic Locking
Pessimistic concurrency locks the database row when data is read and it ensures that transactions do not update the same entity at the same time, which can simplify application code, but it limits concurrent access to the data which can cause bad scalability and may cause deadlocks. Pessimistic locking is better for applications with a higher risk of contention among concurrent transactions. 

Pessimistic locking guarantees that once a transaction has obtained a pessimistic lock (long-term database locks) on an entity instance:

No other transaction (whether a transaction of an application using the Java Persistence API or any other transaction using the underlying resource) may successfully modify or delete that instance until the transaction holding the lock has ended.

If the pessimistic lock is an exclusive lock (LockModeType.PESSIMISTIC_WRITE or LockModeType.PESSIMISTIC_FORCE_INCREMENT), that same transaction may modify or delete that entity instance.

A persistence provider may use an underlying database platform's SELECT FOR UPDATE statements to implement pessimistic locking if that construct provides appropriate semantics, or the provider may use an isolation level of repeatable read.

Pessimistic lock modes
These lock modes are used to immediately obtain long-term database locks. Any locks must be obtained immediately and retained until transaction completes (commits or rolls back).

If transaction calls lock(entity, LockModeType.PESSIMISTIC_READ) or lock(entity, LockModeType.PESSIMISTIC_WRITE) on an object, the entity manager must ensure that dirty read nor non-repeatable read occurs.

If transaction calls lock(entity, LockModeType.PESSIMISTIC_FORCE_INCREMENT) on a versioned object, the entity manager must ensure that dirty read nor non-repeatable read occurs and must also force an update (increment) to the entity's version column.


4.     API to use
There are multiple APIs to specify locking an Entity: 
1.     EntityManager methods: lock, find, refresh
2.     Query methods: setLockMode 
3.     NamedQuery annotation: lockMode element