Creating Resource Managers

In addition to using the classes in System.Transactions for managing transactions, you can also use them to define your own resource managers. These resource managers can then participate in transactions with databases, MSDTC, message queues, and more. There are three basic steps to defining a resource manager:

1. Create an enlistment class. This class is used to track the resource manager's participation in the transaction. That is, this is the class that will vote on whether the transaction should complete or be rolled back. This class should implement the IEnlistmentNotification interface.

2. Enlist the new enlistment class in the transaction. There are two main ways the class may participate in the transaction: EnlistDurable or EnlistVolatile. You use EnlistDurable if your resource manager stores data permanently, such as in a file or database. EnlistVolatile is used if your resource manager stores its information in memory or in some other nonrecoverable location.

3. Implement the methods of the IEnlistmentNotification interface to react to the states of the transaction. The IEnlistmentNotification interface provides four methods: Prepare, Commit, Rollback, and InDoubt. Commit and Rollback are self-explanatory, used at These two phases of the transaction. Prepare is called before Commit, to determine whether it is possible to commit the transaction. Finally, InDoubt is called if the transaction is questionable. This can happen if the transaction coordinator has lost track of one of the resource managers.

Why would you define your own resource managers, rather than simply use an existing one such as SQL Server? You might need to store data in another database that does not directly participate in transactions. Alternately, you may want to enable a normally nontransactional component with transactional behavior. For example, the cache in ASP.NET doesn't support the addition of items using transactions. You could create a resource manager that wraps the ASP.NET cache and adds support for commit and rollback of entries. This might be part of a system in which you want to use the cache as an in-memory data store. While this would work without the transactions, adding transactional support would ensure that if the database write fails for any reason, then the entry could be rolled back out of the cache.

0 0

Post a comment