Virtually all commercially oriented applications that update data sources require transaction support. Transactions are used to ensure the integrity of a system's state contained within one or more data sources by providing the four basic guarantees of the well known ACID acronym: atomicity, consistency, isolation, and durability.
For example, consider a Web-based retail application that processes purchase orders. Each order requires three distinct operations that involve three database updates:
- The inventory level must be reduced by the quantity ordered.
- The customer's credit level must be debited by the purchase amount.
- A new order must be added to the orders database.
It is essential that these three distinct operations be performed as a unit and in an atomic fashion. They must all succeed, or none of them must succeed-any alternative would compromise data integrity. Transactions provide this and other guarantees.
There are a number of approaches that you can adopt to incorporate transaction management into your data access code. Each approach fits into one of two basic programming models:
- Manual transactions. You write code that uses the transaction support features of either ADO.NET or Transact-SQL directly in your component code or stored procedures, respectively.
- Automatic (COM+) transactions. You add declarative attributes to your .NET classes that specify the transactional requirements of your objects at run time. This model allows you to easily configure multiple components to perform work within the same transaction.
Both techniques can be used to perform local transactions (that is, transactions performed against a single resource manager such as SQL Server 2000) or distributed transactions (that is, transactions performed against multiple resource managers located on remote computers), although the automatic transaction model greatly simplifies distributed transaction processing.
You might be tempted to use automatic (COM+) transactions to benefit from an easier programming model. This benefit is particularly apparent in systems where you have many components that perform database updates. In many scenarios, however, you should avoid the additional overhead and performance reduction that result from this style of transaction model.