Building scalable distributed systems that efficiently perform enterprise-critical functions is incredibly challenging. Microsoft developed COM+ to help. COM+ is a sophisticated runtime environment for COM components. It is designed to make the development of scalable systems easier and is the foundation for higher-level frameworks such as BizTalk and Site Server Commerce Edition. But you can't use COM+ effectively if you don't understand how it works.
Transactional COM+ explains how COM+ works and shows readers how to use the technology to its fullest potential as a framework for developing scalable applications. It examines the theory behind COM+, including the nature of scalability, why traditional object-oriented models are inappropriate for scalable systems, and the importance of transactions. The book explores how the two basic atoms of context and causality are used to implement COM+ runtime services. It introduces apartments and activities and the role they play in controlling concurrency in a COM+ process. It also introduces transaction streams and explains how they are used to integrate objects and transactions. Ewald shows how just-in-time activation and object pooling together change the relationship between a client and an object and reveals the importance of HTTP and MSMQ as communication protocols that offer significant advantages over DCOM. Most important, the author explains the influence all these factors have on the design of scalable COM+-based systems.
Practical in its approach, Transactional COM+ goes beyond the rationale behind the technology and the details of its implementation to present concrete guidelines for using COM+ to build applications that scale.
Click below for Sample Chapter related to this title:
Identity in COM.
Implementing Named Objects.
The Problem with Sharing COM Objects.
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.
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.
Thinking about Roundtrips.
A Complex Problem.
A Possible Solution.
A Much Better Solution.
Thinking about Roundtrips Again.
The Linker Switch Story.
The Windows Process Loader.
How COM+ Works.
From Consoles to Contexts.
Contexts as Objects.
Object Context Interfaces.
Using Object Context.
Where Do Contexts Come From?
Libraries and Servers.
Why Library Applications?
Changing the Contents of the Catalog.
How Causality Works.
Causalities as Objects.
Call Context Interfaces.
Using Call Context.
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?
Context-Aware Code Revisited.
A Different Way of Looking at the World.
Some Other Observations.
Where Do Apartments Come From?
Remote Object Creation.
Cross-Apartment Call Overhead.
Raw-Configured Classes Revisited.
Where Do Activities Come From?
Detecting the Presence of an Activity.
Allocating STA Objects to Apartments.
Enabling Object Pooling.
Controlling the Size of a Class's Pool.
Implementing Pooled Classes.
The GIT Trick (and Why It Doesn't Work).
An Exception to the Rules.
Object Pooling Guidelines.
How JITA Works.
Flipping the Done Bit.
The AutoComplete Attribute.
Lies, Damn Lies, and Statistics.
Higher Level APIs.
Enter the Distributed Transaction Coordinator.
Starting a Distributed Transaction.
Enlisting a Connection.
The Two-Phase Commit Protocol.
Distributed Transaction Complexities.
Distributed Transaction Propagation.
A Race Condition.
Enter Transaction Streams.
Where Do Transaction Streams Come From?
Detecting the Presence of a Transaction Stream.
Creating and Propagating a Distributed Transaction.
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.
Correctness versus Performance.
Five Degrees of Isolation.
Implementing Isolation Using Locks.
Implementing Isolation Using Versions.
Choosing an Isolation Level.
Specifying Isolation Levels.
Isolation Levels and OLE DB.
Isolation Levels and the DTC.
Isolation Levels and COM+.
Bring Your Own Transaction.
Timeouts and the DTC.
Timeouts and COM+.
Timeouts and OLE DB.
Optimistic Application-Level Locking.
Pessimistic Application-Level Locking.
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.
Transaction Outcome Notifications.
Server.Execute and Server.Transfer.
ASP Pages and Raw-Configured Classes.
ASP Pages and Object Context.
HTTP + XML = RPC.
SOAP and HTTP.
Applying Message Queuing.
Machines, Processes, and Protocols.
Processors and Helpers.
A Simple Logical Model.
A Simple Physical Model.
Accessing Processors via HTTP.
Transactions and Data Access.
Accessing Data Efficiently.
Some Final Advice.
Using a Pooled Connection.
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.
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