HAPPY BOOKSGIVING
Use code BOOKSGIVING during checkout to save 40%-55% on books and eBooks. Shop now.
Register your product to gain access to bonus material or receive a coupon.
Building enterprise-scale distributed applications is incredibly difficult. Microsoft built COM+ to help, but most developers don't understand it well enough to achieve their goals. In Transactional COM+, Tim Ewald gives developers the comprehensive foundation they need to build business-critical systems with COM+. Ewald explains exactly what problems COM+ aims to solve -- including why it is so difficult to build scalable systems using traditional object-oriented techniques, and how object-oriented style must change in order to build enterprise-scale distributed systems. Next, Ewald introduces COM+ in detail, explaining why COM+ works the way it does, and what the technology's behavior implies about designing effective systems with COM+. Understand how COM+ exposes runtime services to developers; how to leverage application server technologies in the COM+ environment; and the key up-front design decisions you need to make to achieve maximum performance and scalability. Throughout the book, Ewald presents concrete guidelines and best practices for COM+ development -- and shows exactly what common mistakes to avoid. For enterprise developers working on Windows 2000 platforms, there's never been a more valuable resource. For all enterprise developers and designers who are familiar with COM and are now seeking to build distributed systems with COM+ and Windows 2000.
Click below for Sample Chapter related to this title:
ewald03.pdf
1. Scalability.
Scalability Basics.
Identity.
Identity in COM.
Sharing Identities.
Implementing Named Objects.
The Problem with Sharing COM Objects.
Identity Revisited.
Implementing Named Objects with Key-Based Logical Identity.
Implementing Named Objects on Top of a Database.
What Has Been Gained?
The Object-per-Client Model.
Transactions.
Enter Transactions.
Clients and TMs and RMs, Oh My!
Local Transactions and Distributed Transactions.
The Transactions and Scalability Paradox.
Integrating Objects and Transactions.
Using Transactions Explicitly.
Using Transactions Implicitly.
Applying Transactions.
Thinking about Roundtrips.
A Complex Problem.
A Possible Solution.
A Much Better Solution.
Thinking about Roundtrips Again.
Processor Objects.
Summary.
The Linker Switch Story.
An Experiment.
The Windows Process Loader.
How COM+ Works.
From Consoles to Contexts.
Cross-Context Calls.
Contexts as Objects.
Object Context Interfaces.
Using Object Context.
Where Do Contexts Come From?
The Catalog.
Applications.
Libraries and Servers.
Why Library Applications?
Configured Classes.
Custom Attributes.
Changing the Contents of the Catalog.
Context Flow.
Causality.
How Causality Works.
Causalities as Objects.
Call Context Interfaces.
Using Call Context.
Summary.
Context Relativity.
The Problem.
Marshaling Interface Pointers.
The Global Interface Table.
Context Relativity in Day-to-Day Life.
The Cost of Contexts.
A Context for Every Object.
The Cost of Contexts in Time.
The Cost of Contexts in Space.
Are Contexts Worth the Price?
Limiting Context.
Nonconfigured Classes.
Raw-Configured Classes.
Context-Aware Code Revisited.
A Different Way of Looking at the World.
Subtle Complexities.
Custom Marshaling.
Some Other Observations.
Summary.
Apartments.
Apartment Types.
Where Do Apartments Come From?
Threading Models.
Default Contexts.
Remote Object Creation.
Cross-Apartment Calls.
STA Complexities.
Cross-Apartment Call Overhead.
Apartment Guidelines.
Raw-Configured Classes Revisited.
Activities.
Enter Activities.
Where Do Activities Come From?
Detecting the Presence of an Activity.
Allocating STA Objects to Apartments.
Serializing Calls.
Activity Reentrancy.
Activity Deadlock.
Activity Guidelines.
Summary.
Object Pooling.
Enabling Object Pooling.
Reusing Objects.
Controlling the Size of a Class's Pool.
Implementing Pooled Classes.
Accessing Context.
Managing Resources.
The GIT Trick (and Why It Doesn't Work).
An Exception to the Rules.
Object Pooling Guidelines.
Just-in-Time Activation.
Enabling JITA.
How JITA Works.
Flipping the Done Bit.
The AutoComplete Attribute.
JITA Notifications.
JITA Guidelines.
Lies, Damn Lies, and Statistics.
Summary.
Local Transactions.
OLE DB.
Higher Level APIs.
Distributed Transactions.
Enter the Distributed Transaction Coordinator.
Starting a Distributed Transaction.
Enlisting a Connection.
The Two-Phase Commit Protocol.
Distributed Transaction Complexities.
Distributed Transaction Propagation.
Connection Management.
A Race Condition.
Declarative Transactions.
Transactional Objects.
Enter Transaction Streams.
Where Do Transaction Streams Come From?
Detecting the Presence of a Transaction Stream.
Creating and Propagating a Distributed Transaction.
Autoenlisting Connections.
Controlling a Declarative Transaction's Outcome.
Flipping the Happy Bit.
The Four Possible States of a Transactional Object.
Root Objects and HRESULTs.
Transaction Stream Caveats.
Transaction Guidelines.
Summary.
Correctness versus Performance.
Five Degrees of Isolation.
Implementing Isolation Using Locks.
Implementing Isolation Using Versions.
Choosing an Isolation Level.
Isolation-Level Guidelines.
Specifying Isolation Levels.
Isolation Levels and OLE DB.
Isolation Levels and the DTC.
Isolation Levels and COM+.
Bring Your Own Transaction.
ISOFLAGs.
Deadlocks.
Avoiding Deadlocks.
Detecting Deadlocks.
Timeouts and the DTC.
Timeouts and COM+.
Timeouts and OLE DB.
Application-Level Isolation.
Optimistic Application-Level Locking.
Pessimistic Application-Level Locking.
Summary.
HTTP.
HTTP Messages.
HTTP Connection Management.
Internet Information Server.
Mapping Requests to Files.
Mapping Requests to Processes.
Mapping Requests to Contexts and Apartments.
Processing Requests in Parallel.
Active Server Pages.
Processing ASP Requests.
Transactional Pages.
Transaction Outcome Notifications.
Server.Execute and Server.Transfer.
ASP Pages and Raw-Configured Classes.
ASP Pages and Object Context.
HTTP + XML = RPC.
SOAP Messages.
SOAP and HTTP.
Applying SOAP.
Message Queuing.
Transactional Messaging.
Applying Message Queuing.
Summary.
Machines, Processes, and Protocols.
Machine Architecture.
Process Architecture.
Protocols.
Processors and Helpers.
A Simple Logical Model.
A Simple Physical Model.
Accessing Processors via HTTP.
Transactions and Data Access.
Accessing Data Efficiently.
Middle-Tier State.
Some Final Advice.
An Example.
IObjectConstruct.
IObjectControl.
IConn.
Using a Pooled Connection.
Source Code.
Application Property Pages.
Class Property Pages.
Interface Property Pages.
Method Property Pages.
I am (metaphorically speaking) the man on the cover of this book. Or at least I was four years ago. That's when I first encountered the Microsoft Transaction Server (MTS), the precursor to COM+, and knew that my life as a COM developer had changed forever. I very rapidly discovered that the traditional COM object models I was used to did not work in the MTS environment. That annoyed and fascinated me, so I set out to understand why. At first I was blind in my belief that the MTS team had things all wrong--that its creators did not understand distributed objects at all. Over time, however, I came to see why MTS worked the way it did. The answer, quite simply, was scalability.
MTS was designed to simplify the development of scalable distributed applications, and everything it did was in service of that goal. Viewed in that light, the things MTS did with objects (e.g., not sharing them between clients and deactivating them when their transactions ended) finally made sense to me. While all of this was happening, I was spending a lot of time writing and teaching classes about MTS. I met a number of developers who were struggling the same way I had and who needed help. Like me, they wanted to know how MTS worked, why it worked that way, and, most important, how to design systems that used it. It became clear to me that I had a story to tell and that I had to write this book.
It took a long time. In fact, the writing process took so long that this book isn't about MTS at all, but its descendant, COM+.
COM+ is a runtime environment that provides services to instances of classes that declare their desire to use the services. For example, if a class declares that it needs causality-based call synchronization, the COM+ runtime makes sure that only one logical thread of action invokes an instance's methods at a time. Or, if a class declares that it needs a distributed transaction, the COM+ runtime makes sure that one is available. COM+-based systems can be written in C++, Visual Basic 6, or any other COM-friendly language today; and the systems in C#, Visual Basic 7, or any other Common Language Runtime-friendly language tomorrow. The COM+ runtime serves as the foundation for many higher-level technologies, including Internet Information Server (IIS), Active Server Pages (ASP), Site Server, Application Center 2000, and Biztalk Server 2000.
COM+ is the cornerstone of a framework of technologies designed to support the development of large-scale distributed applications on the Windows platform. The current, shipping version of the framework is called Windows DNA. The next version is called .NET. Both versions have similar overall architectures that are based on three assumptions about the needs of scalable systems:
From these assumptions, both frameworks derive three basic principles:
COM+ is designed to make it easier to develop systems that adhere to these principles. It first assumed this position in the Windows DNA framework, and it retains it as we move forward into the .NET arena.
Transactional COM+: Building Scalable Applications is about how and why COM+ works and how to build COM+-based applications. You cannot write software to solve a problem unless you understand the problem's essential nature and general solution, as well as the full details of the technology you are using. To that end, in the abstract, this book is about the design of scalable systems. In the concrete, it is about the mechanics of the COM+ runtime, including its use of processes, contexts, causalities, threads, objects, transactions, and communication protocols.
Here is a brief description of each chapter in the book.
Chapter 1, Scalability, describes the basic problem of scalability, explains why scalable systems use transactions, and why they do not use traditional object models. It evolves the basic object model used in COM+-based systems.
Chapter 2, Atoms, describes context and causality, the two basic constructs on top of which all of the COM+ runtime services are built. It explains how both constructs relate to objects and how objects can interact with them.
Chapter 3, Mechanics, examines the relationship between contexts and objects, including the context relativity of interface pointers and the overhead that contexts represent in both time and space.
Chapter 4, Threads, introduces apartments and activities, the two higher-level constructs COM+ uses to regulate an object's degree of thread affinity and synchronization, respectively.
Chapter 5, Objects, focuses on object pooling and just-in-time activation (JITA) and how these services change the lifecycle of an object in order to use resources more efficiently. Special attention is paid to deconstructing the myths about the scalability benefits that JITA provides.
Chapter 6, Transactions, explores the mechanics of local and distributed transactions and introduces transaction streams, the higher-level construct COM+ uses to associate objects with distributed transactions.
Chapter 7, Isolation, discusses the basic techniques databases use to stop transactions from interfering with one another while at the same time maximizing concurrency and therefore throughput. Cross-transaction application-level locking schemes are also covered.
Chapter 8, Protocols, examines the integration between the Internet Information Server and COM+, including how ISAPI DLLs and ASP pages relate to contexts, apartments, activities, and transaction streams. In addition, SOAP and MSMQ are covered.
Chapter 9, Design, provides general advice on the design of COM+-based systems. Topics include implementing client tasks using one or more transactions; efficient data access; middle-tier, shared-state, and per-client conversation state management; and the inherent tension between scalability and reusability.
There are also four appendices. Appendix A, Toward .NET, covers the shift to .NET and explains how CLR classes take advantage of COM+. Appendix B, Building a Better Connection Pool, shows how to use object pooling to build a database connection pool that is more flexible than the one provided by OLE DB (and used by ADO). Appendix C, Debugging, provides useful information that makes debugging COM+ code easier. Appendix D, Catalog Attributes and Component Services Explorer Property Pages contains diagrams that map catalog attributes to the user interface elements on Component Services Explorer property pages.
This book is intended for developers who are designing and implementing COM+-based systems. It assumes that you know how to implement COM classes and how to write a simple ASP page. It also assumes that you know how to use the COM+ and IIS administration tools, the Component Services Explorer (CSE), and the Internet Services Manager, respectively.
There are three COM+ topics that I did not include in this book. First, while this book mentions COM+ role-based security at a couple of points in the narrative where it becomes relevant, it does not include a complete treatment of the topic because it has already been covered in detail in Keith Brown's excellent book, Programming Windows Security.
Second, I chose to ignore the two ancillary COM+ services--Queued Components (QCs) and Loosely Coupled Events (LCEs)--because both mechanisms have significant limitations that render them useless in the general case. Specifically, although QCs can be used to send messages asynchronously into a COM+ server process, they cannot be used to send messages to other processes, that is, back to a client process. Although LCEs make it possible for a publisher to send an event to multiple subscribers without having to know who they are, the default delivery mechanism is a synchronous, blocking method call. You can make LCEs asynchronous by using them with QCs, but then events can only be fired into COM+ server processes. These problems make both services essentially useless for bidirectional client-server communication (they may in some circumstances be useful for server-server communication). In general, I discard both QCs and LCEs in favor of the Microsoft Message Queue, which makes it easy to build equivalent functionality without these unfortunate limitations.
Third, I did not include Compensating Resource Managers (CRMs) because of a lack of both time and space.
This is not a COM+ cookbook. However, I have done my best to provide as much concrete advice as possible to help you understand how to design and implement COM+-based systems. Specific pieces of advice are identified as "Rules."
There are fewer rules in later chapters, a simple reflection of the fact that as topics get more complex there are fewer concrete guidelines on how to do things. The final chapter compensates for this by offering general advice on system design that follows the rules defined earlier.
Like COM+, this book is programming language-neutral. It speaks in generic terms whenever possible, but covers language-specific issues when necessary. Most of the sample source code in this book is written in C++, although there are some examples in Visual Basic and JavaScript . I chose C++ partly because it is the only language that allows you to explore all the dark corners of COM+ and partly because it is my personal language of choice (or it was until C# came along). Also, most of the sample code in this book is written in a style I picked up from my friend Chris Sells. It makes heavy use of ATL smart types (e.g., CComPtr, CComBSTR, etc.) and poor-man's exception handling, that is, returning from the middle of functions. Neither my language nor my style should be seen as significant in any way; you should write your COM+ classes in whatever language and style you desire.
This book includes a Web site, which features sample code and other resources. The URL is http://www.develop.com/books/.
I have done my best to ensure that this book is free of errors. However, given the scope of the work, especially spelunking through the dark corners of the COM+ runtime, there are bound to be some issues. If you find a bug, please post it to the book's Web site, where I'll maintain an up-to-date list of fixes.
First and foremost, I would like to thank Sarah Shor for sharing her life with me. Never doubt that you come before all technology. Thank you also to the rest of my family for letting me ignore you for so long. And a special thank you to Alan Ewald for always being willing to share his experiences and insights about the design of distributed systems.
Thank you to all of my technical colleagues at DevelopMentor, the incredibly special community in which I am privileged enough to work. By participating in seemingly endless conversations about how COM+ works, you have influenced this work more than you know. A special thank you to Craig Andera, Dan Sullivan, Martin Gudgin, Jon Flanders, Bob Beauchamin, Stu Halloway, Simon Horrell, Keith Brown, and Chris Sells for believing that I had an interesting story to tell. And an incredibly special thank you to Don Box for knowing I had a song in my heart that I needed to sing and for helping me live a rich and fulfilling technical life. Thank you to everyone else at DevelopMentor, too. You have all been very patient with me while I finished this project. Thanks especially to Mike Abercrombie for understanding that my technical work had to come first.
Thank you to Simon Horrell, Dan Sullivan, Bob Beauchamin, Stu Halloway, Martin Gudgin, Alan Ewald, and Mary Kirtland of Microsoft for reviewing chapters and providing feedback. Thank you to all the students, conference attendees, and mailing list participants who have provided feedback about different parts of this story too. Thank you to Joe Long of Microsoft for answering questions about the mechanics of various COM+ runtime services and to Jonathan Hawkins of Microsoft for explaining the relationship between .NET and COM+.
Thank you to David Chappell for writing my foreword and for dressing so well. You give us all something to aspire too.
Thank you to everyone at Addison-Wesley who helped produce this book, including Marilyn Rash for speeding production despite my endless delays; John Wait for explaining some of the inner workings of the technical publishing industry; Carter Shanklin for signing my contract (before leaving Addison-Wesley to pursue other aims); and, most importantly, my editor Kristin Erickson for suffering through this with me and for still being willing to accept my phone calls.
And finally, thank you to Microsoft for creating the technologies that have kept me occupied for the past ten years. COM+ was quite a puzzle; keep them coming.
Tim Ewald