Multi-Tier Architecture

Multi-Tier Architecture The Three Tier Model Business applications today all access data as part of their core functionality. As relational database servers gained in popularity 20 years ago, the industry moved from a one tier (mainframe) model to a client server model where we had a client performing the presentation logic and most of the business logic and the server with the data storage and some business logic in the form of stored queries. By the early 1990s this model broke down due to high maintenance costs and a lack of a separation of concerns and we moved to a three-tier architecture as shown in the figure below. draw:frame} Three-tier architecture enforces a logical (and sometimes physical) separation of three major concerns: Presentation: the user interface components. The goal of separating the logic is twofold: First there is a performance gain by having the database server focus only on database storage and retrieval. Specific hardware and topologies (such as RAID) are used for database storage and access that are different from an “application server” or middle tier of business objects and logic. In addition with powerful client machines it made sense to push UI processing down to the client.

Second was the separation of concerns principle. By separating out the logic of a system, you can easier maintain the overall system, reuse code, and keep associated logic and code in one location. *The n-*Tier Model {draw:frame} The Problem with the nTier Architecture The n-tier architecture has been very successful. Most sophisticated applications today use some form of the n-tier model. Years ago to support this model, enterprises would have as many as five different job titles around the data centric business application.

The job titles were: Data Modeler Database Administrator SQL Programmer Object Modeler Application Developer The data modeler would design the physical tables and relationships. The DBA would create the tables, maintain them and come up with an index and physical disk strategy and maintenance plan. The object modeler would build and object model (or API) and map behaviors to methods. The SQL programmer would work with the object modeler and application developer and write stored procedures and views under the guidance of the DBA.

The application developer would use the object model components and would “glue” the application together. The Object-Relational Impedance Mismatch Database normalization theory, based on mathematics, encompasses different strategies than object oriented theory, which is based on software engineering principles. Database tables model data and prescribe storage techniques. Objects model data and behavior. Data Access Layers (DALs) The impedance mismatch has no easy solution, there are fundamental differences in the database normalization theory and object oriented theory.

To bridge the gap as best as you can and to reduce the amount of code you have to write for database access developers have taken to write data access layers (DALs). The goal of a DAL is to decouple the data access code from the object model, allowing the object model to evolve according to its behaviors and the database to evolve based on its specific needs. A DAL should have these characteristics: Be completely independent of the object model. In other words the DAL should place no constraints on the object model.

The DAL should be able to be ripped out and replaced with minimal to no impact. The problem with DALs is that they are time consuming to write and not easily reusable from application to application. This is where ORMs come in. Object Relational Mapping (ORM) To overcome the impedance mismatch in a DAL you have to understand and implement the process of mapping objects to relational database tables. Class attributes will map to zero, one, or many columns in a database table. If there is proper mapping and persistence ignorance, the developer should nly have to worry about working with the objects in the domain model and the DAL takes care of the rest. One way to facilitate this is to use an Object Relational Mapping or ORM. In addition to mapping and commands, ORMs should also integrate with development IDEs such as Microsoft Visual Studio (or Eclipse), provide caching techniques, integrate with source code version control software, and provide a testable framework. This will enable better developer productivity while saving the developer from having to write the DAL from scratch.

Multi-Tier Architecture A “typical” production multi-tier application built with OpenAccess might have the structure below: Entities (or Model): It contains your persistent classes. The project for this layer is “OpenAccess Enabled” to define Persistent Classes (PCs) and includes database mapping info in the config file. The persistent classes in this project can be created via the Forward or Reverse Mapping OpenAccess wizards. Data Layer (Optional): This layer is optional since the actual “data plumbing” is handled “automatically” inside OpenAccess.

You can skip this layer or use it for storing your LINQ queries and returning data to your business layer. Business Layer: It provides “Repository” (or “Manager”) classes that define operations on the data model objects in the database. This layer is also “OA Enabled” to consume persistent classes, which adds an ObjectScopeProvider to the project (but does not add database mapping info to project) Service Layer (Optional): To build an application that is ready for client-oriented technology (like Silverlight and ASP.

NET AJAX 4. 0), it is usually smart to build a service layer on top of your business logic. The service layer consumes your business layer “data manager” classes and exposes the operations as service endpoints. Presentation Layer: Consumes business layer repositories (if no service layer) or consumes services. The presentation layer can be completely ignorant of OpenAccess and it has no need to be “OA Enabled. ” The figure below demonstrates the relationship of architectural layers in diagram form: {draw:frame} Transactions

Data is maintained in a consistent state by OpenAccess in concert with ACID principles: Concurrency Before talking about how OpenAccess controls concurrency behavior, let’s look at how things can go wrong. We saw in the threading example how concurrent access to the same object caused an exception. Much more subtle errors can occur when multiple transactions read and write to the same objects. Depending on the type of operations and the order they are executed, various kinds of concurrency anomalies can occur.

Dirty Read occurs when a transaction changes a value and a second transaction reads the value before the first transaction is committed or rolled back. If the first transaction rolls back the transaction, then the second transaction contains an unintended value. Lost Update occurs when two transactions read the same record then modify the object independently. The transaction that is committed last overwrites the earlier transaction values. Non-Repeatable Read occurs when a transaction reads an object, a second transaction writes to the object and the first transaction reads a second time.

Because the second read receives a different set of values the read is said to be “non-repeatable”. This issue can also cause inconsistent states between objects that should have some relationship based on reading both objects at one time. Phantom Read occurs when a transaction queries a range of data, a second transaction changes this range of data (either adding or deleting), and the first transaction reads the same range of data a second time. The second read will produce data different from the first read.