分享关于过程的事务处理类

  1 using System;
  2 using System.EnterpriseServices;
  3 using System.Runtime.InteropServices;
  4 using System.Reflection;
  5 
  6 [assembly: ApplicationActivation(ActivationOption.Library)]
  7 [assembly: ApplicationID("77769CB1-A707-11D0-989D-00C04FD444E4")]
  8 [assembly: ApplicationName("SAF.Transaction")]
  9 namespace MyControl.SAFApplication
 10 {
 11     /// <summary>
 12     /// Interface each transaction controller must implement.
 13     /// </summary>
 14     public interface ITransactionController
 15     {
 16         object ExecuteMethod(object o, string method, params object[] p);
 17         void Rollback();
 18         void Commit();
 19     }
 20 
 21     /// <summary>
 22     /// TransactionControllerBase is the base class for serviced components in SAF.Transaction.
 23     /// It provides a way to execute business method as part of the transaction context and abilities
 24     /// to commit and rollback transactions.
 25     /// </summary>
 26     public abstract class TransactionControllerBase : System.EnterpriseServices.ServicedComponent,ITransactionController
 27     {
 28     
 29         public virtual object ExecuteMethod(object o, string method, params object[] p )
 30         {
 31             try
 32             {
 33                 //use the reflection to invoke the business method within the current transaction scope.
 34                 return o.GetType().InvokeMember(method,BindingFlags.InvokeMethod,null,o,p);
 35             }
 36             catch (Exception ex)
 37             {
 38                 //if exception occurs, mark the current transaction as such so that we can
 39                 //rollback the transaction later.
 40                 if (ContextUtil.IsInTransaction)
 41                 {
 42                     ContextUtil.DisableCommit();
 43                 }
 44                 //rethow the exception to notify the caller.
 45                 throw ex;
 46             }
 47         }    
 48     
 49         /// <summary>
 50         /// Rollback method set abort the current transaction.
 51         /// </summary>
 52         public virtual void Rollback()
 53         {
 54             //if it is part of a transaction, abort it.
 55             if (ContextUtil.IsInTransaction)
 56             {
 57                 ContextUtil.SetAbort();
 58             }
 59         }
 60 
 61         /// <summary>
 62         /// Commit method commit the current transaction if all the transaction vode
 63         /// are good.
 64         /// </summary>
 65         public virtual void Commit()
 66         {
 67             //check if it is in a transaction
 68             if (ContextUtil.IsInTransaction)
 69             {
 70                 //check if the transaction vote is good. if so, set complete on the transaction
 71                 //otherwise, abort the transaction.
 72                 if (ContextUtil.MyTransactionVote == TransactionVote.Commit)
 73                 {
 74                     ContextUtil.SetComplete();
 75                 }
 76                 else
 77                 {
 78                     ContextUtil.SetAbort();
 79                 }
 80             }
 81         }    
 82     }
 83 
 84 
 85     /// <summary>
 86     /// Provide the Manager class that 
 87     /// clients interact when creating different type of transaction compnent.
 88     /// </summary>
 89     public class TransactionManager
 90     {
 91         /// <summary>
 92         /// Return a new serviced component that supports transaction
 93         /// </summary>
 94         /// <returns>SupportTransaction object</returns>
 95         public static ITransactionController GetSupportTransactionController()
 96         {
 97             return new SupportTransaction();
 98         }
 99 
100         /// <summary>
101         /// Return a new service component that require transaction
102         /// </summary>
103         /// <returns>RequireTransaction object</returns>
104         public static ITransactionController GetRequireTransactionController()
105         {
106             return new RequireTransaction();
107         }
108 
109         /// <summary>
110         /// Return a new service component that require new transaction
111         /// </summary>
112         /// <returns>RequireNewTransaction object</returns>
113         public static ITransactionController GetRequireNewTransactionController()
114         {
115             return new RequireNewTransaction();
116         }
117 
118         /// <summary>
119         /// Return a new service component with no transaction
120         /// </summary>
121         /// <returns>NoTransaction object</returns>
122         public static ITransactionController GetNoTransactionController()
123         {
124             return new NoTransaction();
125         }
126 
127         /// <summary>
128         /// Helper method that will rollback array of ITransactionController objects
129         /// </summary>
130         /// <param name="txControllers">ITransactionController array</param>
131         public static void Rollback(params ITransactionController[] txControllers)
132         {
133             foreach (ITransactionController txController in txControllers)
134             {
135                 if (txController != null)
136                 {
137                     txController.Rollback();
138                 }
139                 
140             }
141         }
142 
143         /// <summary>
144         /// Helper method that will commit array of ITransactionController objects
145         /// </summary>
146         /// <param name="txControllers">ITransactionController array</param>
147         public static void Commit(params ITransactionController[] txControllers)
148         {
149             foreach (ITransactionController txController in txControllers)
150             {
151                 if (txController != null)
152                 {
153                     txController.Commit();
154                 }
155                 
156             }
157         }
158 
159 
160         /// <summary>
161         /// Release the resource held by the serviced components
162         /// </summary>
163         /// <param name="txControllers">ITransactionController array</param>
164         public static void DisposeAll(params object[] txControllers)
165         {
166             foreach (object txController in txControllers)
167             {
168                 if (txController != null)
169                 {
170                     try
171                     {
172                         //check is txController is a service compnen.
173                         if (txController is System.EnterpriseServices.ServicedComponent)
174                         {
175                             //destory the serviced component
176                             ((ServicedComponent)txController).Dispose();
177                         }
178                     }
179                     catch (Exception ex){}
180                 }
181             }
182         }
183     }
184     
185     /// <summary>
186     /// Transaction controller that supports transaction.
187     /// </summary>
188     [ProgId("SupportTransaction")]
189     [Guid("E42F5FFF-823B-4F20-AE80-B13A3C991112")]
190     [Transaction(System.EnterpriseServices.TransactionOption.Supported)]
191     public class SupportTransaction : TransactionControllerBase
192     {
193         public SupportTransaction()
194         {
195         }
196     }
197 
198     
199     /// <summary>
200     /// Transaction controller that requires transaction
201     /// </summary>
202     [ProgId("RequireTransaction")]
203     [Guid("E42F5FFF-823B-4F20-AE80-B13A3C991113")]
204     [Transaction(System.EnterpriseServices.TransactionOption.Required)]
205     public class RequireTransaction : TransactionControllerBase 
206     {
207         public RequireTransaction()
208         {
209         }
210 
211         
212     }
213 
214     /// <summary>
215     /// Transaction controller that requires new transaction
216     /// </summary>
217     [ProgId("RequireNewTransaction")]
218     [Guid("E42F5FFF-823B-4F20-AE80-B13A3C991114")]
219     [Transaction(System.EnterpriseServices.TransactionOption.RequiresNew,Isolation=TransactionIsolationLevel.ReadCommitted)]
220     public class RequireNewTransaction : TransactionControllerBase 
221     {
222         public RequireNewTransaction()
223         {
224         }        
225     }
226 
227     /// <summary>
228     /// Transaction controller that doesn't support transaction
229     /// </summary>
230     [ProgId("NoTransaction")]
231     [Guid("E42F5FFF-823B-4F20-AE80-B13A3C991115")]
232     [Transaction(System.EnterpriseServices.TransactionOption.NotSupported)]
233     public class NoTransaction : TransactionControllerBase
234     {
235         public NoTransaction()
236         {
237         }    
238     }
239 }
240 

下面提供一个事务处理类的测试实例:具体如下
  1 using System;
  2 using System.Reflection;
  3 //using SAF.Transaction;
  4 using System.Data;
  5 using System.Data.SqlClient;
  6 
  7 namespace MyControl.SAFApplication
  8 {
  9     /// <summary>
 10     /// Demo that show SAF.Transaction can be used wrap multiple 
 11     /// calls into different transactions
 12     /// </summary>
 13     class Class1
 14     {
 15 
 16         //[STAThread]
 17         static void TestMain(string[] args)
 18         {
 19             DataAccess data = new DataAccess();
 20             //clean up the table 
 21             data.ClearupTable();
 22             
 23             //--------------Sample 1--------------------------------//
 24             ITransactionController transaction_A= TransactionManager.GetRequireTransactionController();
 25             try
 26             {
 27                 transaction_A.ExecuteMethod(data,"AddNewRecord",new object[2]{"xin","111111111"});
 28                 transaction_A.ExecuteMethod(data,"AddNewRecord",new object[2]{"mike","222222222"});
 29                 //this call will fail due to duplicate key error.
 30                 transaction_A.ExecuteMethod(data,"AddNewRecord",new object[2]{"john","111111111"});
 31                 TransactionManager.Commit(transaction_A);
 32             }
 33             catch (Exception ex)
 34             {
 35                 TransactionManager.Rollback(transaction_A);
 36                 //additional error handling code.
 37             }
 38             finally
 39             {
 40                 //release the resource used by the serviced component
 41                 TransactionManager.DisposeAll(transaction_A);
 42             }
 43 
 44             //--------------Sample 1 result --------------------------//
 45             //None of three record is inserted to the employee table. //
 46             //--------------------------------------------------------//
 47 
 48             //clean up the table 
 49             data.ClearupTable();
 50             
 51             //--------------Sample 2----------------------------------//
 52             ITransactionController transaction_C= TransactionManager.GetRequireNewTransactionController();
 53             ITransactionController transaction_B= TransactionManager.GetRequireTransactionController();
 54             
 55             try
 56             {
 57                 transaction_B.ExecuteMethod(data,"AddNewRecord","xin","111111111");
 58                 transaction_B.ExecuteMethod(data,"AddNewRecord","mike ","222222222");
 59                 try
 60                 {
 61                     //add an important employee. Add him regardless whether other
 62                     //employees are added to table successfully
 63                     transaction_C.ExecuteMethod(data,"AddNewRecord","bill","333333333");
 64                     TransactionManager.Commit(transaction_C);
 65                 }
 66                 catch (Exception ex)
 67                 {
 68                     TransactionManager.Rollback(transaction_C);
 69                 }
 70                 //this call will fail due to duplicate key error.
 71                 transaction_B.ExecuteMethod(data,"AddNewRecord",new object[2]{"john","111111111"});
 72                 TransactionManager.Commit(transaction_B);
 73             }
 74             catch (Exception ex)
 75             {
 76                 TransactionManager.Rollback(transaction_B);
 77                 //additional error handling code.
 78             }
 79             finally
 80             {
 81                 //release the resource used by the serviced component
 82                 TransactionManager.DisposeAll(transaction_B,transaction_C);
 83             }
 84             
 85             //--------------Sample 2 result ---------------------------//
 86             //----------Only bill is added to the employee table.------//
 87             //---------------------------------------------------------//
 88 
 89 
 90             //clean up the table 
 91             data.ClearupTable();
 92         
 93             //--------------Sample 3-----------------------------------//
 94             ITransactionController transaction_D= TransactionManager.GetNoTransactionController();
 95             ITransactionController transaction_E= TransactionManager.GetSupportTransactionController();
 96             ITransactionController transaction_F= TransactionManager.GetRequireTransactionController();
 97             try
 98             {
 99                 data.AddNewRecord("xin","111111111");
100                 transaction_D.ExecuteMethod(data,"AddNewRecord","mike","222222222");
101                 transaction_E.ExecuteMethod(data,"AddNewRecord","bill","333333333");
102                 //this call will fail due to duplicate key error.
103                 transaction_F.ExecuteMethod(data,"AddNewRecord","john","111111111");
104                 TransactionManager.Commit(transaction_D,transaction_E,transaction_F);
105             }
106             catch (Exception ex)
107             {
108                 TransactionManager.Rollback(transaction_D,transaction_E,transaction_F);
109                 //additional error handling code.
110             }
111             finally
112             {
113                 //release the resource used by the serviced component
114                 TransactionManager.DisposeAll(transaction_D,transaction_E,transaction_F);
115             }
116 
117             //--------------Sample 3 result --------------------------------------------//
118             //only xin, mike, bill are added to the employee table. John is not added.--//
119             //--------------------------------------------------------------------------//
120 
121         }
122 
123     }
124     /// <summary>
125     /// DataAccess provides access to testing db.
126     /// </summary>
127     public class DataAccess
128     {
129         private string connection;
130         public DataAccess()
131         {
132             connection ="Initial Catalog=SAFDemo;Data Source=localhost;Integrated Security=SSPI";
133         }
134         /// <summary>
135         /// Insert a record to the table
136         /// </summary>
137         /// <param name="name"></param>
138         /// <param name="ssn"></param>
139         public void AddNewRecord(string name,string ssn)
140         {
141             
142             SqlConnection conn = new SqlConnection(connection);
143             try
144             {
145                 conn.Open();
146                 SqlCommand command = new SqlCommand("insert into employees values('" + name + "','" + ssn + "')",conn);
147                 command.ExecuteNonQuery();
148             }
149             finally
150             {
151                 conn.Close();
152             }
153 
154         }
155 
156         /// <summary>
157         /// Clearn up the table for the next test
158         /// </summary>
159         public void ClearupTable()
160         {
161             SqlConnection conn = new SqlConnection(connection);
162             try
163             {
164                 conn.Open();
165                 SqlCommand command = new SqlCommand("delete from employees",conn);
166                 command.ExecuteNonQuery();
167             }
168             finally
169             {
170                 conn.Close();
171             }
172         }
173     }
174 }
175 
posted @ 2006-05-16 22:34  ccs  阅读(507)  评论(0编辑  收藏  举报