wcf应用
- 格式:doc
- 大小:93.50 KB
- 文档页数:9
此示例演示客户端协调事务的用法,以及为了控制服务事务行为而对ServiceBehaviorAttribute 和OperationBehaviorAttribute 进行的设置。
持久写入服务器日志表依赖于客户端协调事务的结果- 如果客户端事务未完成,Web 服务事务可以确保不会提交对数据库的更新。
下面我们把程序的代码依次列出来。
契约和服务类的代码:using System;using System.Configuration;using System.Data.SqlClient;using System.Globalization;using System.ServiceModel;using System.Transactions;namespace Microsoft.ServiceModel.Samples{// Define a service contract.[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Sampl es", SessionMode = SessionMode.Required)]public interface ICalculator{[OperationContract][TransactionFlow(TransactionFlowOption.Mandatory)]double Add(double n);[OperationContract][TransactionFlow(TransactionFlowOption.Mandatory)]double Subtract(double n);[OperationContract][TransactionFlow(TransactionFlowOption.Mandatory)]double Multiply(double n);[OperationContract][TransactionFlow(TransactionFlowOption.Mandatory)]double Divide(double n);}// Service class which implements the service contract.[ServiceBehavior(TransactionIsolationLevel=IsolationLevel.Serializable,TransactionTimeout="00:00:30",ReleaseServiceInstanceOnTransactionComplete=false,TransactionAutoCompleteOnSessionClose=false)]public class CalculatorService : ICalculator{double runningTotal;public CalculatorService(){Console.WriteLine("Creating new service instance ");}[OperationBehavior(TransactionScopeRequired=true,TransactionA utoComplete=true)]public double Add(double n){RecordLog(String.Format(CultureInfo.CurrentCulture,"Addin g {0} to {1}",n,runningTotal));runningTotal = runningTotal + n;return runningTotal;}[OperationBehavior(TransactionScopeRequired=true,TransactionA utoComplete=true)]public double Subtract(double n){RecordLog(String.Format(CultureInfo.CurrentCulture, "Subt racting {0} from {1}", n, runningTotal));runningTotal = runningTotal - n;return runningTotal;}[OperationBehavior(TransactionScopeRequired=true,TransactionA utoComplete=false)]public double Multiply(double n){RecordLog(String.Format(CultureInfo.CurrentCulture, "Mult iplying {0} by {1}", n, runningTotal));runningTotal = runningTotal * n;return runningTotal;}[OperationBehavior(TransactionScopeRequired=true,TransactionA utoComplete=false)]public double Divide(double n){RecordLog(String.Format(CultureInfo.CurrentCulture,"Divid ing {0} by {1}",n,runningTotal));runningTotal = runningTotal / n;OperationContext.Current.SetTransactionComplete();return runningTotal;}public static void RecordLog(string recordText){// Record the operations performedif (ConfigurationManager.AppSettings["usingSql"] == "true "){using (SqlConnection conn = new SqlConnection(Configu rationManager.AppSettings["connectingString"])){conn.Open();SqlCommand cmdLog = new SqlCommand("INSERT into L og(Entry,AddTime) VALUES (@Entry,@AddTime)", conn);cmdLog.Parameters.AddWithValue("@Entry", recordTe xt);cmdLog.Parameters.AddWithValue("@AddTime", DateTi me.Now.ToString());cmdLog.ExecuteNonQuery();cmdLog.Dispose();SqlCommand cmdCount = new SqlCommand("SELECT COUN T(*) FROM Log", conn);string rowCount = cmdCount.ExecuteScalar().ToStri ng();cmdCount.Dispose();Console.WriteLine("Writing row {0} to database : {1}", rowCount, recordText);conn.Close();}}else{Console.WriteLine("Nothing row : {0}",recordText);}}}}服务端的配置文件:<?xml version="1.0" encoding="utf-8" ?><configuration><appSettings><add key="usingSql" value="true"/><add key="connectingString" value="Data Source=.\SQLExpress;Attac hDbFilename=|DataDirectory|\SampleDB.mdf;Integrated Security=True;Use r Instance=True"/></appSettings><system.serviceModel><services><service name="Microsoft.ServiceModel.Samples.CalculatorService " behaviorConfiguration="CalculatorServiceBehavior"><host><baseAddresses><add baseAddress="http://localhost:8000/ServiceModelSampl es/service"/></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfigura tion="TransactionalBinding" contract="Microsoft.ServiceModel.Samples.ICalculator"></endpoint><endpoint address="mex" binding="mexHttpBinding" contract="IM etadataExchange"></endpoint></service></services><bindings><wsHttpBinding><binding name="TransactionalBinding" transactionFlow="true">< /binding></wsHttpBinding></bindings><behaviors><serviceBehaviors><behavior name="CalculatorServiceBehavior"><serviceMetadata httpGetEnabled="true"/><serviceDebug includeExceptionDetailInFaults="false"/> </behavior></serviceBehaviors></behaviors></system.serviceModel></configuration>客户端的代码:using System;using System.Transactions;namespace Microsoft.ServiceModel.Samples{class Program{static void Main(string[] args){// Create a clientCalculatorClient client = new CalculatorClient();// Create a transaction scope with the default isolation level of Serializableusing (TransactionScope tx = new TransactionScope()){Console.WriteLine("Starting transaction");// Call the Add service operation.double value = 100.00D;Console.WriteLine(" Adding {0}, running total={1}", value, client.Add (value));// Call the Subtract service operation.value = 45.00D;Console.WriteLine(" Subtracting {0}, running total={1} ",value, client.Sub tract(value));//throw new Exception();// Call the Multiply service operation.value = 9.00D;Console.WriteLine(" Multiplying by {0}, running tota l={1}",value, client.Mul tiply(value));// Call the Divide service operation.value = 15.00D;Console.WriteLine(" Dividing by {0}, running total= {1}",value, client.Div ide(value));Console.WriteLine(" Completing transaction");plete();}Console.WriteLine("Transaction committed");// Closing the client gracefully closes the connection an d cleans up resourcesclient.Close();Console.WriteLine("Press <ENTER> to terminate client."); Console.ReadLine();}}}正常情况下,我们运行客户端,会发现数据表中添加了ID从1到4的4条记录。