
by J. Eddie Gulley
Modern development of multiple-tier (n-tier) client/server (CS) applications requires the orchestration of many different components. Often, these components have to be designed, developed, and tested separately from within many non-integrated tools. This lack of integration increases the learning curve, increases costs, and decreases productivity for developers.
Microsoft Visual Studio 97 finally brings together a complete toolkit for CS application developers. Included with Visual Studio 97 Enterprise Edition, the visual database tools provide database design and management support to developers through the Integrated Development Environment (IDE) implemented with Visual InterDev and Visual C++ and as an add-in for Visual Basic 5.0. These tools tightly integrate the project workspaces and Microsoft SQL Server for full life-cycle development of complex CS applications.
Before you dive into the design tools, you need to consider some of the issues involved in the design of a solid database on which your CS application will operate. These issues are as important to address as those involving language selection, overall system architectures, and other tasks required in the development of accurate, stable applications.
Some of the more important issues to consider in good database design are
By not addressing these issues, you aren't providing your client/server project every chance at success. Worse, you could doom it to failure.
The importance of good logical and physical design in SQL Server is easy to underestimate. The necessity for appropriately capturing requirements early in the life cycle is important in all components of a CS application, but is perhaps more necessary in the context of the back-end database. The database in a CS architecture is normally much less resilient when changes are made later in the development cycle than other components. This is true because the database in the CS model is usually the foundation for the entire system.
Front-end applications have three functions: They allow data to be input by users, pass data to middle-tier business logic components for calculation or persistent storage in the database, and present results back to users. These requirements for user-services components create an inherent dependency on the middle-tier components and--even more important--on the data-services (RDBMS) components in the CS model. Thus, even minor changes to the database structure can flow throughout the CS model, causing even more changes to the dependent components. Changes to front-end graphical user interface (GUI) components usually don't require changes in other layers.
One accepted way of lessening the risk of changes to the database is to make a habit of documenting the structure of your database. A graphical method of doing this is entity relationship diagramming, which provides a picture of the tables and their relationships with other tables in the database (see Figures 3.1 and 3.2). Such a picture of the database allows developers and users to see database design decisions in an understandable format. Developers can easily walk through the diagram with end users to ensure that requirements are met. By being able to visualize the database design, you easily can see how data is stored and perhaps see problems inherent in a particular database design. It's beyond the scope of this book to teach you the intricacies of data modeling and design, but I highly encourage you to seek out other sources of instruction on this important development concept.
FIG. 3.1
The logical data model represents a process or processes in the context of the users
or actors of that process.
FIG. 3.2
The physical data model represents how a logical model is stored physically on a
relational database.
A good entity relationship (ER) diagramming tool can serve to define the database at various levels of abstraction or models. A logical model of the database, in Figure 3.1, provides a method for communicating with and soliciting feedback from end users during the analysis phases of development. This logical view also provides end users and other database users with only the information they need for their purposes, and hides details important only to database designers and developers.
The physical model in Figure 3.2 provides a detailed view of the design of the database and provides for the actual representation of the schema applied to the database. The physical database schema consists of tables, columns, and relationships from the logical model and also individual column data types, defaults, table and column constraints, indexes, and tables constructs for resolving many-to-many relationships. With Visual Studio 97, designers can not only provide graphical representation of the database, but also can use that model as a means of creating the physical data structures within the relational database management system (RDBMS) through script generation and execution against a SQL Server database.
ON THE WEB:You can get more information about data modeling or entity relationship diagramming from web pages of computer-aided software engineering (CASE) tool vendors. For background on the concepts of and standards for entity relationship diagramming, visit the National Institute of Standards and Technology's (NIST) home page at http://nemo.ncsl.nist.gov/idef. Here, you can view or download Federal Information Processing Standard (FIPS) Publication 184 "Integration Definition for Information Modeling (IDEF1X)." IDEF1X, the NIST standard for data modeling, is implemented in most major database CASE tools.
CS systems that use a relational database management system such as SQL Server for data storage and retrieval often must integrate large amounts of Standard Query Language (SQL) statements into middle-tier components. These middle-tier components must allow the insertion, editing, deletion, and retrieval of data stored in the RDBMS. Often, much data-specific logic is required before these services can be fulfilled. For instance, the data may need to be validated from end-user entry before being inserted, or special business rules may need to be applied to the data before it's affected.
When the logic for data manipulation is placed into the middle tier, the full advantages of the RDBMS engine isn't realized. Middle-tier component languages usually aren't designed for manipulating large sets of data, but for processing of individual records at a time or for performing calculations on a few discrete values.
SQL is a mathematically based language designed for the manipulation and processing of large amounts of related data. By encapsulating the logic for data manipulation in stored procedures, the services necessary for fulfilling the data manipulation are performed in the same CS layer where that data is stored. Common sense tells you that this is a better partitioning of services within layers in the CS model and should provide better performance than SQL statements embedded in external language components. In most cases, the techniques used in external languages require multiple translations of the SQL string before its being sent to the SQL engine. These multiple translation layers come from the passing of SQL strings through data-access libraries such as ODBC and add overhead in the processing of the SQL commands.
Some of the more technical reasons why stored procedures are good choices for data- manipulation logic include performance and security. The main performance gain in using stored procedures is the location of the processing. Stored procedures are precompiled and executed within the context of the SQL Server engine. This negates network latency in execution speed, because the processes that manipulate data reside in the same memory and processing space as the data structures that store the data. In a networked environment, this can equate to large performance gains.
You can actually use stored procedures as a security tool. User permissions over database objects must be tightly controlled in a CS environment. Stored procedures can let you build up a distinct layer between the physical storage of data and the users of the data. Rather than give users permissions over all tables in which data is stored, you can restrict them to permissions over the execution of stored procedures. Users don't need to have select permissions on a table if they have permissions over a stored procedure that, after some validation logic, does the selection for them and returns a result set. In this model, rather than build an elaborate management scheme of a hierarchical groups-and-permissions structure on top of tables, you can give users permissions to execute a few stored procedures that act as a public interface to the underlying data storage.
NOTE: Many other sources cover these concepts for stored procedure development. One good reference is Stephen Wynkoop's Special Edition Using Microsoft SQL Server 6.5, published by Que Corporation.
The visual database tools encompass a full range of features to give you control over the physical database schema required for your Visual Studio 97 project. Four components make up the visual database tools:
The Database Designer provides a graphical depiction of your database structure. Although not adhering to popular semantic and notational standards for entity relationship diagramming, the Database Designer provides a great tool for modeling and creating database structures without requiring you (the developer) to learn constructs of complex Database Definition Language (DDL). The Database Designer also allows you to experiment with the design of your SQL Server database without affecting the physical database until you're ready to do so. This capability to experiment lends itself well to the iterative development cycles popular today. The Database Designer also lets you make changes to a database while automatically migrating data to the changed structure if that data doesn't violate any rules of the changed structure.
The Source Editor for SQL Server provides a modern development environment for stored procedures and triggers. In traditional stored procedure development, you couldn't set breakpoints and step through code. You would try to compile the completed procedure and receive vague error messages--no line numbers, no ability to view the value of a variable. With Visual Studio's Source Editor, you have all these capabilities plus the ability to step into stored procedures and SQL statements embedded in your application. You can also set breakpoints and watch variables just like you can with almost all programming language Integrated Development Environments. It sure beats trial and error and the use of print statements to narrow down where in the source code errors are occurring.
The Query Designer allows you, graphically or in SQL, to create and execute queries against ODBC-compliant databases. Anyone familiar with the query-by-example (QBE) feature in Microsoft Access will welcome the ability to apply the same concept to more powerful CS databases.
The Data View component provides a graphical browser to a connected database. Data View resembles and acts as an explorer for your database. You can view database diagrams, tables, triggers, stored procedures, and views contained within your database from within your development environment. Without Data View, you often had to run a separate application, such as the MS SQL Server Enterprise Manager, to obtain an organized look at the objects in your database. Although this isn't necessarily a problem, having this capability built into your normal environment lets you view your entire system from within the same integrated development component.
The next section and the section "Stored Procedure Development with Visual Studio 97" provide more detail on how to use the Database Designer and the Source Editor for SQL Server stored procedures. These two components focus more on the design issues previously introduced and are newer additions to Microsoft's programming tools.
The purpose of this section isn't to teach you how to perform data modeling but to show you how to use the Data Designer to depict your database design graphically and create the database objects required to physically implement your design. Before you begin, you must create the necessary devices for storing your database and create a blank database to access through the Data Designer.
You can create devices and databases within SQL Server with the SQL Enterprise Manager or the ISQL interface provided with SQL Server. A developer's edition of SQL Server is included with Visual Studio 97 Enterprise Edition. Specific details on creating and managing devices and databases for SQL Server are found in the SQL Server's Administrators Companion. After you accomplish these tasks, follow these steps to start up the Database Designer and add a data connection:
FIG. 3.3
The Visual Database Tools are an integrated part of Visual Basic.
NOTE: A little time spent learning the security model of SQL Server will greatly aid you in troubleshooting during development and when you begin integrated testing of large CS applications. SQL Server security knowledge can also boost your productivity when chasing down vague error messages that, at their root, are merely a matter of database object permissions.The SQL Server security model is broken down into three modes: Integrated, Standard, and Mixed. With Integrated Security, SQL Server uses Windows NT's authentication services for login validation for all connections. Only trusted connections are allowed when using Integrated Security. Standard Security uses SQL Server's own login process. Mixed Security allows SQL Server to service login requests based on whether the requesting connection is trusted. Under Mixed Security, SQL Server uses Integrated for trusted connections and Standard for nontrusted connections.
Now that you've successfully created and connected to your database, it's time to create a diagram. The following steps outline how to create a database diagram from within the Developer's Studio IDE. The Developer's Studio is used for Visual C++, Visual InterDev, and Visual J++. All three language environments use the Developer's Studio for development and for the Visual Database Tools. Visual Basic also uses the Developer's Studio IDE for the Visual Database Tools.
FIG. 3.4
You can add a database diagram to a specific database available through a project's
data connection.
To begin creating tables in your diagram, follow these steps:
Table 3.1 lists the properties you can set for each column with the Database Designer.
| Property Name | Definition |
| Column Name | Name you want to use for the column. All column names must be unique within a table and conform to SQL Server rules for database object identifiers. |
| Datatype | System- or user-defined datatype for the column. |
| Length | Used to specify the maximum number of characters for char types or digits for numeric types. |
| Precision | The total number of digits that can be stored on either side of a decimal point. |
| Scale | The total number of digits that can be stored on the right side of a decimal point. The scale value must be equal to or less than the precision for the column. |
| Allow Nulls | Used to specify whether a column should allow NULL values. If NULLs are allowed, you can provide a default. |
| Default Value | Used to denote a default value for insertions. Defaults can be literal values or Transact-SQL function calls such as the getdate() function for returning the current system date and time. If a default isn't provided, columns that don't explicitly provide a value will be assigned NULL. |
| Identity | The identity property allows columns to contain auto-generated values to uniquely identify each table row. Identity columns are handy for sequential numbers as unique identifiers. |
| Identity Seed | Beginning value for future generations in an identity column. The next insertion into the table begins with this seed value. If not given, this value defaults to 1. |
| Identity Increment | Amount that an identity value increments from the previous record in the table. For instance, if the identity increment value is set at 10, each subsequent insertion adds 10 to the previous row's column value to generate the current identity value. |
CAUTION: Before making a decision on the nullability of a column, make sure that you understand the consequences of multiple-value logic and SQL queries. Careful consideration given to this contentious issue can possibly prevent subtle logic errors from finding their way into your code. NULLs can be said to have multiple possible values, such as the attribute not applying to a particular record, the value may be unknown for a record, or the value known but not captured yet for a record. Queries that include columns containing NULLs must account for the possible logical meanings of the NULL values; also, care certainly should be taken to properly constrain such queries.
Figure 3.5 shows a completed table named Client represented in the sample client/server application demonstrated throughout this book. You can find the application at http://www.gasullivan.com/vs97book/.
The only thing left to do for this table is to denote the primary key(s) by following these steps:
FIG. 3.5
The Database Designer can represent the logical or physical view of a database.
Here is the physical view of the sample Client table.
In more formal development shops, you might work under more guarded database access. In these cases, you'll want to save your diagram to a text script file, submit it to your database administrator (DBA) for review, and let him run the script against the database for object creation.
After you create more than one table on the diagram, you might need to relate one or more tables. Table relationships are represented by foreign key constraints on dependent table columns. For instance, an invoice record might be related to a client record through a foreign key relationship on the AccountNumber column. This requires that any invoice record entered into the invoice table must reference through its AccountNumber column a valid Client record in the Client table.
To create foreign key relationships in a database diagram, click within the parent table's key columns and drag to the child table's foreign key column (see Figure 3.6). After you draw the required relationship, you're prompted to create the relationship, as shown in Figure 3.7.
The dialog box in Figure 3.7 defaults to an appropriate name for the foreign key constraint that will be created and allows you to verify that the correct columns in the parent and child tables are included in the constraint. By default, other options are also enabled, such as checking existing data, if any, against the new column constraint and checking the relationships for inserts and updates and for replication. Generally, you should accept the defaults unless your database requirements dictate otherwise.
FIG. 3.6
A dashed line between two tables in a data-base represents foreign key relationships
in progress.
FIG. 3.7
You can access the properties of the selected relationship through the database diagram.
After the relationship is created, you see the related tables attached on the diagram through a three-dimensional bar with a key icon on the parent end and a double-link chain on the child end. This notationally represents a one-to-many relationship in entity-relationship diagramming.
Continue adding tables and relationships as necessary to complete the diagram of your database. After you finish, you can save all changes to the database immediately or generate a script file as noted earlier.
You can also experiment further with the diagram. For instance, right-click any object to bring up menu options for different views of objects. You can view each table with full column names and parameters, just view the tables and key field columns, or just view tables with name spaces. You can also choose to view properties of any object on your diagram. By looking at the properties for a table, you can examine and alter indexes and other constraints for that object.
Figure 3.8 shows you the completed diagram for the sample application included at the site http://www.gasullivan.com/vs97book/.
FIG. 3.8
The completed diagram for the same Time & Billing application.
The Database Designer also lets you create smaller views of a large diagram. This is often helpful in large CS projects where the database contains hundreds of tables and a developer is concerned only with a portion of the database dealing with a particular set of tables. You can create diagram views easily by inserting a new diagram and dragging the required tables from the data view to the blank diagram.
Another use for the diagramming tool is so that you can experiment with different layouts of tables and relationships without affecting the underlying database until the design is finished. You can accomplish this by creating a diagram, dragging existing tables to it, and altering their structure as desired. Just be sure to remember not to save the diagram to your database until you're sure that the design is what you want, or you lose any previously created structures.
With some experimentation and practice, you should be able to create complex databases with the Database Designer included with Visual Studio 97. This can bring more of an engineering approach to development projects and get developers and users interacting during the requirements phase for more successful projects.
If you've ever had to develop stored procedures for SQL Server, you're aware of the lack of tools to support this development. Unlike application developers, SQL procedure programmers haven't historically had tools such as advanced editors, debugging facilities, or even good ways to test stored procedures. Often, you had to enter your procedure code into a text editor or directly into the ISQL interface provided with SQL Server. There was no on-the-fly syntax checking, color coding, or consistent indentation for procedure development. Debugging and testing were even worse--you often would submit your completed procedure to the SQL engine and receive error messages, which gave you only enough information to figure out the problem after a great deal of experience.
Debugging your procedures consisted of placing print statements at key points throughout to try to identify which areas were properly processed and which weren't. Testing stored procedures required you to set up the affected database objects with data to meet referential integrity requirements and then manually enter procedure calls with correct parameters. After that, you had to run select queries against affected tables to identify whether your procedure affected the underlying data correctly.
Visual Studio 97 brings the SQL developer into the modern age. Fairly complete support is provided in Visual Basic 5.0 as an included add-in and is integrated into the Visual InterDev and Visual C++ 5.0 IDE. You can now use your familiar editor for entering procedure code, with all the frills you're used to in your favorite development environments. Properly indented text, color coding, and syntax checking are all available in the editor.
Another new feature included with Visual Studio 97 is SQL stored-procedure debugging, using the same debugging components available with VC++ and Visual InterDev. VB has a separate Transact-SQL (T-SQL) debugger provided as an add-in, available automatically when testing your Remote Data Object (RDO) code or separately on demand.
If you're familiar with the Visual C++ IDE and debugging facilities, you'll be up and running fairly quickly with procedure development and debugging. If you're familiar with VB, you'll soon learn about the Transact-SQL debugger and see how you can apply the same productivity to your SQL development as to the rest of your application code tasks.
Begin by ensuring that T-SQL debugger is installed. If you chose to install all the enterprise tools when you installed Visual Basic 5.0, you should have a new option, T-SQL Debugger, on the Add-Ins menu. If not, you'll need to repeat the setup process, choosing a custom install and opting to Select All for the enterprise tools selection.
In addition to installing the T-SQL debugger on your client machine, you need to ensure that your database installation is SQL Server 6.5 and is running at least Service Pack 1. Then you need to run the Sdi_nt4.exe setup program on your SQL Server machine. You can find the Sdi_nt4.exe application on the client machine on which you installed VB 5.0 in the \CliSrv\Tsql directory.
NOTE: To verify the server installation, ensure that SDI.DLL is resident in your \MSSQL\BINN directory on a Windows NT installation of SQL Server, or \MSSQL\BIN on a MS-DOS, 16-bit Windows, or Windows 95-based client.
You can access the T-SQL Debugger via one of several methods: explicitly during procedure-design time, implicitly by stepping through Visual Basic code that make calls to your stored procedures, or explicitly from within a Visual Basic UserConnection object.
NOTE: To automatically step into a stored procedure, make sure that you've selected Automatically Step Into Stored Procedures in the T-SQL Debugger options. You can access the T-SQL Debugger options by choosing Tools, T-SQL Debugger Options from the Visual Basic menu.
You can explicitly invoke the debugger during design time by choosing Add-Ins, T-SQL Debugger from the menu. This brings up the Batch T-SQL Debugger dialog box (see Figure 3.9).
FIG. 3.9
The T-SQL Debugger settings properties allow you to set the parameters for your
debugging session.
On the first tabbed page, enter information pertaining to the data source name with which you want to access the database. Available sections include
The Lock Type property in the T-SQL Debugger dialog box refers to the type of concurrency control the debugging session should have over the resultset being affected. The named items in the listbox refer to Remote Data Objects (RDO) constants that refer to specific values which can be assigned to the LockType property of RDO resultset objects. Table 3.2 describes the available lock types.
| Lock Type | Description |
| rdConcurReadOnly | Resultset is read-only. No modifications can be made to the data. |
| rdConcurLock | The resultset locks all associated data pages. Pessimistic in that it assumes that no other users will need the same data. |
| rdConcurRowVer | Optimistic lock type in that it assumes that no other user will attempt to change the affected data, so it doesn't lock any of the affected pages. Requires row identifier to be compared against the record in the resultset. If the identifiers match, the modification takes place; if not, an error is generated. |
| rdConcurValues | Version of optimistic lock where no data pages are locked. Requires row-by-row comparison of values before changes can be committed. |
| rdConcurBatch | Optimistic locking where no locks are held but where each change is accumulated in a batch. When the batch is applied, each record is modified according to rules of a lower-level parameter. Status values of each record in a batch are returned. |
The Result Set parameter on the T-SQL Debugger refers to the type of cursor to use with the RDO resultset object in the debugging session. Table 3.3 describes the available resultset types.
| Resultset | Description |
| rdOpenKeyset | Dynamic type cursor where you can still see records changed by other users but not those added by others. You also can't access records deleted by another user. |
| rdOpenForwardOnly | Static type cursor in which you can see records only as they were when you retrieved the recordset. You can't see records added, modified, or deleted by others since you opened your cursor. You can only scroll forward with this cursor type. |
| rdOpenStatic | Similar to forward-only cursor, except that you can scroll forward or backward. |
| rdOpenDynamic | All data additions, modifications, or deletions made to the data in your open cursor are visible. Scrolling in any direction is enabled. |
The Options selection for the T-SQL Debugger session refers to how the session should present its SQL statements to the SQL Server: either directly through the SQLExecDirect Open Database Connectivity (ODBC) API function when rdExecDirect is selected or by preparing a stored procedure for each statement when rdNone is selected.
After the DSN information is entered, you can change to the Stored Procedures page, which is very helpful in the debugging and testing process. This page allows you to
After you select your stored procedure and enter values for any input parameters, you can click the Execute button.
CAUTION: Stored procedures are designed to manipulate or alter data in your database. It's strongly suggested that you select the Use Safe Mode (transaction rollback) for Stored Procedure Calls option in the T-SQL Debugging options. This way, any changes a stored procedure might make can be rolled back on completion of the debugging/testing session.
Now you should be in the T-SQL Debugger interface itself (see Figure 3.10). The interface is made up of a code window (for viewing the actual procedure code being debugged), a local variable watch window, a global variable watch window, and a procedure output window. The simple toolbar gives you ready access to all the debugging options available.
FIG. 3.10
The Code window in the T-SQL Debugger isn't for developing but for viewing code as
you step through it in a debugging session. The other windows are mostly hidden at
the bottom of the T-SQL Debugger window.
The debugging options available in the T-SQL Debugger are as follows:
You also can invoke a separate Call Stack window and a temporary table dump window for viewing the related output. Experienced SQL procedure developers will definitely recognize these features as ones long awaited. If you take time to learn the features well, you should benefit from increased productivity.
In addition to the debugging facilities provided, Visual Studio 97 allows you to create new stored procedures or edit existing ones from within the Microsoft Developer Studio IDE. Data View provides a graphical hierarchy of all database objects for the database related to the data source you have in your project.
To create a new stored procedure, follow these steps:
FIG. 3.11
Stored procedures are written by using the Visual Studio source editor.
TIP: As you write your procedure code, having a printed copy of your data model close by is often handy so you can look up identifier name spellings, data types, and table keys and indexes. Or, you can use the Data View explorer from within the same IDE to explore the properties of tables and columns as you write your procedures.
FIG. 3.12
The context menu available by right-clicking within the Developer Studio Code
window allows you to run or debug your stored procedure.
FIG. 3.13
Stored procedure output varies according to the statements and parameters of your
procedure itself. In this case, the return value indicates success in the insert
of the employee record.
After your procedure is successfully compiled and run, notice that it's added to the Data View hierarchy. It's also ready to be debugged, which you can do either during your application debugging inline with application code, or from the code window by right-clicking the procedure code window and selecting Debug from the pop-up menu.
As you can see, Visual Studio 97 has added some great SQL Server database design and development tools to the CS developer's toolkit. With a little work and experimentation, you should become a more productive database developer with these tools.
Today's systems are often a mix of architectures and technologies. What most of them have in common is that they're of a distributed nature. A distributed system is a dynamic collection of computers linked by a network, running software designed to provide an integrated computing environment to users. Distributed systems can range from single-purpose applications that support business processes to full-service computing facilities that service a broad range of users with a broad range of resources.
Given these complex tasks, a distributed system must be designed and developed in levels of abstraction or architectures. Two main design paradigms have emerged to support distributed architectures:
The following sections will help you understand what client/server and multiple-tier architectures are and how Visual Studio 97 helps in the development of distributed systems. You'll also gain an understanding of how the Internet and intranets (I-nets) are just extensions or alternate design paths for distributed computing, which sit on top of the CS and multitier architectural foundations.
CS computing is at the heart of the Information Technology (IT) industry today. As organizations have moved from a centralized computing environment to client/server, the very description of client/server computing continues to evolve. Generally speaking, client/server computing is the splitting of processes into two or more parts, the client and the server:
As shown in Figure 3.14, function calls implement communication between the client and the server. The client component calls a server function. The client passes parameters (param) to the server function arguments (args). The server processes the request and then returns success/failure codes or provides requested data. The client in turn receives the return from the server and acts on any errors, returns success to its client application, or displays data back to users.
FIG. 3.14
In the client/server mix, two processes cooperate to perform a system service.
One (the client) invokes a function, which takes arguments (args) by passing parameters
to the server process.
To facilitate communication between the client and server across a network, client components must be able to locate and invoke functions on server components. They must also be able to map parameter values to native datatypes. Different machine architectures require that this interprocess communication be able to marshal or translate data from one architecture to another to provide for correct parameter value representation on the client and server.
In reality, any component in a CS environment can act as a server and a client. Often, a component might act as a client to other servers and as a server to other clients. These client and server components can exist within the context of a single machine, but they usually operate in a multiuser environment (see Figure 3.15).
Figure 3.15 shows a typical distributed system. Users are connected to a local network and share network resources, such as file and print services. Applications share data from an RDBMS. Modern business systems increasingly extend this local distributed model by integrating web and other Internet access with the local resources, as well as opening up access to external networks for geographically separated business units or for integration with customer or supplier systems. This orchestration of disparate components and resources creates unique design issues and goals, which you must address in the distributed system.
Distributed CS components have unique issues and goals, which must be addressed in their design. Some of these goals and issues are
FIG. 3.15
In the simple distributed system model, clients (workstations) request services
and resources from network servers hosting services such as file and print and database
services.
Some of the earliest implementations of distributed systems included sharing of print and file services on a local network. Most network operating systems provide for this level of resource sharing by providing such services as standard naming, location directory, and file-handling functions. More recent developments in resource sharing include opening up resources beyond the local boundaries, wide area network (WAN) integration and access to enterprise data, and I-net and remote users.
With the opening up of local networks in distributed computing, concurrent processing and scalability issues increase in importance. Concurrency indicates the need for multiple users or user processes to request the same services and the need for server processes to execute in parallel to fulfill all requests in an efficient manner. Scalability is concerned with the ability of resource managers to service multiple requests simultaneously on an increasingly more frequent basis as larger numbers of users or clients are added to a distributed system.
Openness as a design goal is the capability of a distributed system to remain extensible across disparate user platforms and components. This requirement often requires resources to operate over multiple protocols and provide standard access facilities. The rapid acceptance of standards for database access--such as a common interface for RDBMS servers in the form of the SQL language--is a good example of openness across distributed systems.
Fault tolerance is the capability of systems to recover from failure. Distributed systems must provide hardware redundancy and software recovery features to provide a fault-tolerant environment. Fault tolerance is also related to the capability of a distributed system to provide the necessary high availability of shared resources. Very few businesses could operate without a high degree of systems availability, a need increased by the interrelated demands of a distributed system.
Transparency in distributed systems is the distributed environment's capability to isolate users from the complexities of the distributed implementation. Users shouldn't need to concern themselves with how data is accessed across local or wide area environments. For maximum productivity and efficiency, the distributed system needs to have the appearance of a single system to the user. Transparency is also an important abstraction technique for developers. Developers shouldn't need to know implementation details of shared resource managers, but should be provided with standard interfaces to integrate their components with others.
Visual Studio 97 provides many tools and development technologies to support the requirements of distributed CS systems. In this section, you'll see how the technologies and tools in Visual Studio 97 support the development of systems that support the major design issues and goals.
With Visual Studio 97, you can design and develop distributed client/server systems by taking advantage of standard integrated tools and technologies. Visual Studio 97 supports the following:
One concept that seeks to address some of the major issues involved in the design of distributed systems is multiple-tier architectures. A multiple-tier architecture is an abstraction of processes into distributed objects or components that communicate across multiple machines in a networked environment.
The partitioning of components can be logical or physical. Logically partitioned tiers consists of two or more processes--such as a GUI application and a shared object library DLL--cooperating to fulfill user requests. The processes are located on and execute on the same machine in a logical partition. Logically partitioned applications have many advantages, not the least of which is the capability to change the implementation of components internally without affecting component users. As long as a component's interface remains the same, component developers are free to change or optimize the internal workings of components.
Physically partitioned tiers meet the same definition, but the processes are executed on different machines. A typical example of a physically partitioned tier is a direct link between a Data Entry GUI application and the RDBMS to which it directs transactions to on a networked database server. The server-side logic executes within the RDBMS server through the use of stored triggers or procedures for business rule logic and data validation. Well-designed server procedures provide a well-planned interface for applications to request data services from the RDBMS.
Beyond the two-tier model, multiple-tier systems can exist with many complex structures. Figure 3.16 shows a common three-tier configuration. Additions to this three-tier model are common. The main source of additional tiers comes in the form of specialized "middleware," a component or components that provide program-to-program or program-to-data communication.
Program-to-program communication is the concept of two processes--the client and the server--communicating across a network. The calling of remote functions on server components involves program-to-program communication. Program-to-data communication deals with the use of interface APIs on data stores such as SQL Server. The SQL language enables program communication to access persistent data storage. Open Database Connectivity (ODBC) is an example of middleware implemented in the Windows environment. ODBC allows client applications (or middle-tier business objects) to communicate with an ODBC-compatible data source via SQL.
FIG. 3.16
Multiple-tier architectures come in a variety of different configurations.
In the three-tier model shown in Figure 3.16, you see the architecture typically intended when developers discuss multitier architectures. With this three-tier model, a clear distinction exists over the types of processes handled by each tier. The GUI application is responsible for interacting with users. Typical requirements at the presentation tier are to
The business services tier often serves many functions. In the preceding model, it would typically be responsible for
The middle tier must also provide transaction control. Transaction control is usually a cooperative process between the business services and data services tiers. A business component provides for transaction control by using the RDBMS transaction commit and rollback protocols against changed data. If the business component doesn't get to complete a transaction with the RDBMS before losing the client connection, it might have to roll back any data changes made on the RDBMS. Likewise, the business component must provide for data commits to take place after a transaction is completed successfully and client feedback is provided.
The data services tier in the preceding model is typically represented by a standard RDBMS. The RDBMS provides for several interfaces, which the middle-tier components can use to maintain a connection to the RDBMS server and to provide for data-manipulation functions. The key requirement at this level is standard interfaces to allow SQL calls to be made to the RDBMS server.
Multiple-tier architectures build on the client/server computing model by providing for the communication of components at different tiers through the normal client/server model. You've seen how components interact in the three-tier model. Other numbers of tiers may also be found in client/server systems. Systems using more than three physical or logical tiers are usually doing so for load-balancing purposes. Rather than have all middle-tier software components on one middle-tier application server, they may have some components on one application server and others on other servers. You can also use multiple middle-tier application servers run the same middle-tier components and better balance the load among many users in high-volume systems.
NOTE: The middle-tier components often act as client and server. Server behavior is necessary when handling the request for validation from the GUI, and client behavior when executing the SQL request from the database server.
Why multiple-tier architectures? This question is perhaps one of the hardest to answer when it comes to distributed computing. It's better to ask what advantages are gained by going with distributed computing.
Multiple-tier architectures can allow for the processing of computing tasks to take place where it's best used. Users have gained processing power on their desktops and are gaining the know-how to take advantage of it. Applications designed to take advantage of client computing power can distribute loads across networks to scale processing requirements. The presentation processes are moved off the server to better enable cheaper servers to handle the same load.
Middle-tier business components allow errors to be corrected and rules to be enforced before they're passed to database servers. These types of middle-tier components allow fewer erroneous transactions to consume database resources and enable the resources to better serve good ones. By distributing this logic to other machines on the network for all users to share, business-rule enforcement can be better designed to remain common among several applications, thus providing a more stable enterprise architecture for computing.
Placing the data services tier on a separate database server enables much better availability and fault tolerance in distributed systems. The database server can handle a higher transaction load if it doesn't also have to handle file and print services. It will also be highly unlikely that failures in one machine will migrate to other machines. This capability to isolate system failure to components on different machines is a great strength in distributed computing.
In extremely high-volume data or transaction environments, the data services and business tiers can themselves be replicated to other servers and act as mirror processes either to serve large numbers of users or to support the geographical separation of users. The failure of one process isn't likely to cause the failure of another, thereby ensuring application availability to at least a portion of the user community.
The main goal in designing multitier systems is to provide for scalability. Scalability across large-scale networking or internetworking environments often brings many more issues to deal with as a developer than process-intensive client two-tier applications. In the two-tier model, the database does most of the work. Application front ends make direct database SQL calls and handle all the business logic with process-intensive client applications or database procedures.
The burden for scalability is on the database. The maximum number of user connections or the number of transactions the system can handle is up to the database server. Client applications in two-tier models support one user and have little to do with system performance. Performance is a database issue.
With the design of multitier applications, more and more pressure is on the middle tier to handle scalability to a certain extent. Following is a list of additional requirements for the middle tier:
With the requirements that come with multitier systems, the level of complexity involved in developing multitier applications increases. Applications developers must become more familiar with lower-level functions on local and network operating systems. The margin for error also decreases as multitier systems scale to enterprisewide mission-critical applications.
Visual Studio 97 provides technologies and tools to deal with the complexity of multitier applications. One of the more visible additions to Visual Studio 97 is Microsoft Transaction Server (MTS). MTS simplifies multitier application development by providing much of the infrastructure development preassembled, thus freeing you to concentrate on the business logic of your multitier system.
In addition to providing the transaction-processing functions implied by its name, MTS provides much of the infrastructure processing requirements necessary with multitier applications. MTS takes over the control of the middle tier, taking advantage of Microsoft's Component Object Model (COM) and ActiveX technology. COM provides the glue that enables remote connectivity, interface specifications, and communication mechanisms for networked, distributed components.
MTS takes advantage of COM and ActiveX technology by providing directory services for clients to locate server components and by providing messaging constructs to pass data between application components. The developer is isolated from the details of distributed component communication and just references the appropriate server code. Server code is referenced by instantiating the appropriate server component libraries in the client application. The rest is treated just like local procedure calls.
The directory services that allow COM and ActiveX components to be located and resolved are implemented by the Registry in Windows 95 and Windows NT. Appropriate naming and class lookup routines allow for the registering of process IDs for server components that any client can reference. As the developer, you don't need to worry about these details, but you do need to become familiar with appropriately referencing and calling server components.
MTS also provides Windows NT-level security for multitier applications. MTS extends Windows NT's user- and group-based login permission structures to accommodate the implementation of access control over the public interfaces of COM and ActiveX components. You also can extend MTS security.
MTS provides many features for managing performance and scalability in distributed systems. Specifically, MTS provides thread and process management, maintains database connection pools, and provides support for distributed COM (DCOM).
MTS components provide a thread pool for middle-tier components. When a request is made of a middle-tier ActiveX component, MTS allocates a thread. It then uses that thread to communicate with the ActiveX component, and takes care of deallocating the thread when the process completes. To gain true scalability, you would have to write all this process and thread code yourself. MTS takes this work away from you and allows you to concentrate on more critical business logic in satisfying user demands, which translates into more scalability with less effort on your part.
MTS frees database resources for more scalable solutions by maintaining a similar pool of preconnected database connections. This alleviates the overhead of establishing and de- establishing database connections on a one-for-one basis in response to every data request. As clients are idle, connections can be reassigned to handle other requests--definitely an improvement in resource usage. Again, you're free from having to code your application to handle the complexity of connection pooling for scalability.
MTS can also distribute database transactions across SQL Servers, which is helpful if you need to update more than one database in a single transaction and maintain data integrity with transaction control. MTS does this by providing a common interface to address multiple SQL Servers or resource managers via Microsoft's Distributed Transaction Coordinator (DTC). A resource manager can be any ODBC-compliant relational database.
As you can see in Figure 3.17, MTS doesn't change the look of the multitier model much, but it does provide less complexity for application developers and some basic services that address the design issues involved with multitier architecture design. You're shielded from the complexity of implementing infrastructure-type software components for such tasks as security, transaction control, remote component resolution and location, database connection pooling, and multithreaded control over processes.
FIG. 3.17
This example of a multitier architecture using Microsoft Transaction Server illustrates
the typical multitier model.
With the advent of Internet/intranet (I-net) computing, the development world seems to have been taken by surprise. What is I-net and how does it mix with modern distributed computing? How do developers leverage their experience with CS and multitier development to take advantage of I-net as a computing environment? The following sections answer some of these questions and show how your experience in CS development can be leveraged for I-net development.
The Internet is a large network of networks. Relatively unmanaged, the Internet is a collection of networks, internetworked together to provide for rapid communication and data sharing over a geographically dispersed area. Today, that geographical area just happens to be nearly the entire computing world. It's safe to say that millions of computers are linked via the Internet, and millions of users are taking advantage of the computing resources made available by the Internet.
An intranet is an internal network of a common organization, usually a business or government group, used to share information and facilitate communication among users. Intranets also may be geographically dispersed and vary from the Internet in that only specified users or networks are allowed access. Intranets are distinguished from other internal network systems by their reliance on a Hypertext Transport Protocol (HTTP) or "web-based" application user interface.
Combined, the I-net represents one of the fastest areas of growth today in computing resources and in the development of business systems. Unfortunately, with this growth come even more design issues and questions that must addressed when developing I-net-enabled applications.
When most people think of I-net, the World Wide Web (the web) comes to mind. The web is a client/server-based technology that allows users to access a seemingly endless variety of information from I-nets. The web uses HTTP to request information or services from a web server. Other I-net services implemented as interface protocols are File Transfer Protocol (FTP), used to browse remote file storage and save or retrieve files from remote computers; Telnet, a protocol used to remotely perform processing on a remote computer; and many other protocols for retrieving, sending, or manipulating digital data or processing power on a remote computer.
Most of the Internet-related press today focuses on software developers creating protocols responsible for the transmission of digital information in every form. Java and ActiveX implement a transmission and execution environment for applets and components across I-net environments. Other technologies are concerned with such information services as digitized audio and video.
It's important for you, the developer, to understand that the real action is on the server. As with any other client/server environment, the Internet must provide for scalable performance, standard information access (not just relational data), fault tolerance, and security.
With the cross-platform requirements placed on web browsers, many of these mission-critical requirements must be handled by the server. With I-net applications potentially being required to scale to many thousands of users, handling these issues on the server is perhaps the only answer.
Typically, the client or browser in an I-net environment must only interpret a data stream through the use of a protocol and display the data in the correct format. The server, however, must be able to field requests from potentially thousands of users for a wide variety of information represented by a wide range of media. Text-type data from databases, images from file systems and databases, and other digital multimedia information from a variety of sources must be handled in a responsive manner by the server.
Figure 3.18 shows a typical I-net application architecture. As with any client/server system, I-nets must take advantage of multiple tiers, even more so with the demands for performance and scalability across sometimes unproven network bandwidth.
FIG. 3.18
A typical I-net application architecture using multitier client/server concepts.
When the Internet and the web took us all by storm, most of us were just getting into multiple-tier architectures. A closer look at what an I-net application is and how it works will show you that you can use what you already know for I-net development.
In Figure 3.18, the client application (GUI) has been replaced by a web browser. Web browsers, at their simplest, translate Hypertext Markup Language (HTML) pages requested from a web server and display their contents. Most of you have seen this at work. Some browsers also provide an execution environment for language-code execution (for example, a Java virtual machine for hosting runtime support for applets to execute on any platform). Others provide plug-in support for any number of non-standard protocols used to transmit and display or play all types of multimedia content.
I-net applications are beginning to move beyond the static content popular in the beginning. Corporate IS staffs are being asked to I-net-enable existing applications for broader availability across a broader user base. With the need to open up enterprise data stores and provide legacy system functionality to I-net users, a good solid architecture must be in place. Multitier architectures can be and are being used successfully to provide data access and application functionality via I-net protocols.
With I-net applications, you don't have to retool your servers and throw out your components. With multitier architectures, you can just add the browser as another data user in the client/server mix. With standards, you can allow your HTML pages to interact with server components to provide database access and other server functions. Common business object middleware still can be used to validate data entered by a remote I-net user. Often, the same code used to develop your GUI can be reused in the development of I-net applications implemented on the browser.
At the site http://www.gasullivan.com/vs97book, you'll see an example of common middle-tier objects serving a traditional client/server application and a more modern Active Server Pages (ASP) front end from a SQL Server. Both front-end applications will use the same ActiveX control for client-side processing--proof that multitier architectures, when properly implemented, can provide flexible, distributed solutions.
Visual Studio 97 brings I-net application development into the mainstream. In a typical I-net application, the browser downloads a static HTML document. That browser must support any HTML contained in the document, including any required scripting or unique display rules for the hypertext. One challenge in developing I-net applications this way is making sure that your HTML document can support the widest range of browser features. This is becoming increasingly impossible as vendors rush to add new features to their browsers, and the technology is moving faster than standards can be adopted.
For developers who want to serve as large a user base as possible, this war of browser features can be bewildering and confusing as to the latest standard for tables or another HTML content type. With ASP and Internet Information Server 3.0, Microsoft seems to have solved the browser feature problem by moving the main intelligence in I-net development to the server. (More detailed information concerning ASP and IIS 3.0 can be found in Chapter 13, "An Inside Look at Active Server Pages and Internet Information Server.")
IIS 3.0 supports server-side scripting of HTML for dynamic content generation at access time. ASP is the name of the technology that allows you to develop active HTML components on the server to execute any required code before streaming HTML to the client. ASP remains compatible with almost all browsers, even text-based ones. The dynamic content is interpreted on the server before being pushed to the requesting client. ASP is distinguished from Dynamic HTML in that it's interpreted and generated on the server rather than something that the client web browser must support. Chapter 18, "Dynamic HTML," provides more information about Dynamic HTML.
Before ASP, if you needed to enhance your web site to display enhanced graphics or text, there was no good way of doing it that would be supported by every browser. Now with ASP, you can run scripts on the server to handle the nuances of your special requirements and send the resulting HTML to the browser. With client-side scripting, you can provide dynamic web sites that interact with your users.
The technology behind ASP is simple. You embed scripts inside HTML documents, which in turn are executed by IIS whenever a request is made for that document. The server then generates HTML, based on criteria between the user session and the script included on the page. With IIS 3.0, you can develop Active Server Pages with JScript or VBScript--another opportunity to leverage your existing development knowledge.
In this chapter, you learned about the importance of good database design and how it affects the effectiveness of your application development projects. You learned how to use the tools provided in Visual Studio 97 to help design databases, and got an overview of distributed computing and multitier architectures.
For more information on the topics covered in this chapter, see the following chapters:
© Copyright, Macmillan Computer Publishing. All rights reserved.