In the previous articleArticle"Net short talk about transactions and Distributed Transaction ProcessingI have summarized the transaction processing methods in. NET and simple applications that combine the WCF framework. In transactional operations, we focus on reversible data. To put it bluntly, we can ensure the acid of data. (For the overall model and principle of transactions, see". Net short talk about the nature of transactions"Text), in. the powerful class libraries in the net transaction processing framework help us implement a lot of technical difficulties in transaction transmission and automatic transaction upgrading. At the same time, they also provide a lot of extended interfaces, as long as we are willing to study it, we will always be able to reap the harvest.
This article mainly explains how to use it. NET provides our extended interfaces for resource management within the scope of custom transaction processing. Within the scope of transaction operations, we will not always regard the database as a dependent object, it will not always be an object such as idbtransaction. We need our own transaction resource manager, and we need our own persistent Resource Manager. If possible, we need to develop our own backup persistent storage zone.
Interested friends can go to see our Jiang Jinnan Jiang big brother on the affairs of the article, speak very well: http://www.cnblogs.com/artech/archive/2010/01/31/1660433.html
The following describes how to implement a simple transactional resource manager. In our daily development process, most of the data is stored in the database, and operations within the transaction scope are not allowed to modify non-transactional resources because they are irreversible, there is no resource manager to manage them. When a transaction fails, the modified data cannot be restored to the status before the transaction operation. We can only modify the data in the database and then perform rollback, because the data in the database has the database resource manager for powerful management.[Wang qingpei has all rights reserved. For more information, please sign it.]
When we use idbtransaction for transaction processing, it actually gets a reference to remote transaction processing. For example, the sqltransaction object is the logical transaction Resource Manager, when we use transactionscope for transaction range operations, sqlserver data providesProgramIt can automatically upgrade transactions and register transaction resources. At the end of the process, the two-phase commit protocol can be well performed for final data submission.
Transactional resource manager category:
The. NET transaction model provides several interfaces for you to implement custom resource managers. You can inherit these interfaces to implement resource managers that support single-and two-phase commit protocols.
1. ienlistmentnotification interface: supports the resource manager implementation interface of the two-phase commit protocol.
(Official explanation: Describes the interface that the resource manager should implement to provide the two-phase commit notification callback for the Transaction Manager during registration participation .)
2. isinglephasenotification interface: supports the resource manager implementation interface of the single-phase protocol.
(Official explanation: Describes the resource objects that support single-phase commit optimization to participate in transactions .)
3. ipromotablesinglephasenotification interface: supports the resource manager implementation interface of the single-phase submission protocol that can be upgraded. (Description: the object that is used as the commit delegate for non-distributed transactions within the resource manager .) This object is inherited from the itransactionpromoter interface, which must be automatically promoted to the Resource Manager managed by MSDTC.
ImplementationSystem. Transactions. ienlistmentnotificationInterface to customize the resource manager for the two-phase commit protocol
The following describes how to develop a simple Resource Manager by implementing the ienlistmentnotification interface.
Code1: Resource Manager
Public class ienlistmentnotificationdemo <t, xcopy>: ienlistmentnotification where T: New () Where xcopy: Class {T _ commitfrontvalue; T _ rollbackfrontvalue = new T (); xcopy copy; public ienlistmentnotificationdemo (T, xcopy icopy) {(icopy as iresourcecopy <t> ). copy (_ rollbackfrontvalue, T); _ commitfrontvalue = T; // retain the reference copy = icopy;} # region ienlistmentnotification member public void prepare (P Reparingenlistment preparingenlistment) {// The preparation console in the two-phase commit protocol. writeline ("prepare for submission"); consolekeyinfo key = console. readkey (); If (key. keychar = 'y' | key. keychar = 'y') {preparingenlistment. prepared (); // submit the transaction by voting} else if (key. keychar = 'n' | key. keychar = 'n') {console. writeline ("\ n I vote for the entire transaction rollback:" + _ rollbackfrontvalue); (copy as iresourcecopy <t> ). copy (_ commitfrontvalue, _ rollbackfrontvalue );/ /Roll back the transaction to voluntarily preparingenlistment. forcerollback (); // roll back the transaction by voting. When resource management is incorrect, the system automatically replies to the Data. // because transaction management does not notify the manager of the forcerollback () method.} Public void commit (enlistment) {// try to submit the console. writeline ("transaction attempt commit"); enlistment. done (); // notifies the transaction manager that the participant has completed the submission.} Public void rollback (enlistment) {// handle errors in the transaction activation phase and execute the rollback console. writeline ("operation failed, rollback" + _ rollbackfrontvalue); (copy as iresourcecopy <t> ). copy (_ commitfrontvalue, _ rollbackfrontvalue); // roll back the transaction to enlistment voluntarily. done ();} public void indoubt (enlistment) {// lost contact with other resource managers console. writeline ("lost contact with other resource managers, usually logging"); enlistment. done () ;}# endregion}
This class is a resource manager that supports the two-phase commit protocol, because different resources face different data replication operations. When performing initial data backup, we need to perform different data replication operations on different data types. Therefore, we need a specification to agree.
Code 2: Resource replication Interface
/// <Summary> /// copy Resources in the transaction resource manager. Different resource types have multiple copies. /// </Summary> Public interface iresourcecopy <t> {void copy (T T1, t T2 );}
Code 3: implement data replication of the stringbuilder type
/// <Summary> /// stringbuilder-type data copy object. You need to implement the iresourcecopy generic interface. /// </Summary> public class stringbuildercopy: iresourcecopy <stringbuilder >{# region iresourcecopy <stringbuilder> member public void copy (stringbuilder T1, stringbuilder T2) {t1.remove (0, t1.length); t1.append (t2.tostring () ;}# endregion}
In this way, we have the stringbuilder Data Replication operation class.
Code 4: add the Custom Resource Manager to the transaction
/// <Summary> /// status of the resource management object registered within the transaction range /// </Summary> public class enlistmentdemo {[methodimpl (methodimploptions. synchronized)] // lock the current method to prevent multi-threaded access from compromising transaction resource consistency. Public void start () {// stringbuilder stringvalues = new stringbuilder ("123"); stringbuilder stringvalues2 = new stringbuilder ("456 "); stringbuilder stringvalues3 = new stringbuilder ("789"); stringbuilder stringvalues4 = new stringbuilder ("101112"); // use the resource manager to manage ienlistmentnotificationdemo <stringbuilder, stringbuildercopy> resource = new ienlistmentnotificationdemo <stringbuilder, stringbuil Dercopy> (stringvalues, new stringbuildercopy (); iterator <stringbuilder, stringbuildercopy> resource2 = new iterator <stringbuilder, stringbuildercopy> (iterator, new stringbuildercopy (); iterator <stringbuilder, stringbuildercopy> resourtms= new ienlistmentnotificationdemo <stringbuilder, stringbuildercopy> (stringvalues3, new stringbuild Ercopy (); ienlistmentnotificationdemo <stringbuilder, stringbuildercopy> resource4 = new ienlistmentnotificationdemo <stringbuilder, stringbuildercopy> (stringvalues4, new stringbuildercopy ()); try {using (transactionscope transcope = new transactionscope () {transaction. current. transactioncompleted + = new transactioncompletedeventhandler (commitran_transactioncompleted); // register the transaction Resource Manager, which is required before starting all transactional operations Register Resource Manager transaction first. current. enlistvolatile (resource, enlistmentoptions. none); transaction. current. enlistvolatile (resource2, enlistmentoptions. none); transaction. current. enlistvolatile (resour2010, enlistmentoptions. none); transaction. current. enlistvolatile (resource4, enlistmentoptions. none); // start the transaction operation, which is the active stage of the transaction. Stringvalues. append ("456"); stringvalues2.append ("789"); stringvalues3.append ("101112"); stringvalues4.append ("131415"); transcope. complete (); // start two-phase commit, which is the prepare stage of the transaction.} Catch {console. writeline ("transaction execution error, perform rollback");} // view the value after the transaction operation console. writeline ("result value after the transaction is completed:"); console. writeline (stringvalues + "|" + stringvalues2 + "|" + stringvalues3 + "|" + stringvalues4);} // event Method triggered at the end of the transaction to capture the transaction execution result. Void commitran_transactioncompleted (Object sender, transactioneventargs e) {console. writeline ("transaction completed:"); console. writeline ("ID: {0}", E. transaction. transactioninformation. localidentifier); console. writeline ("distributed ID: {0}", E. transaction. transactioninformation. distributedidentifier); console. writeline ("status: {0}", E. transaction. transactioninformation. status); console. writeline ("isolationlevel: {0}", E. transaction. isolationlevel );}}
Let's take a look at the effect:
Figure 1: transaction commit
Figure 2: Transaction rollback:
In this way, we can well involve the Custom Resource Manager in transaction processing, which is the same for distributed transaction processing, you must register the resource manager before using it within the scope of the transaction operation.
Transaction processing is a huge field. I am only a small application here. I hope everyone can use it.[Wang qingpei has all rights reserved. For more information, please sign it.]