WCF在多个服务中使用事物
步骤1 服务端契约使用强制事务传播流
步骤2 服务端实现使用事务特性
步骤3 host配置中使用支持事务传播的binding
不受4 客户端采用TransactionScope
经销商库存 提供创建的功能呢
namespace GreatWall.VMS.DealerStock.ServiceContract { [System.ServiceModel.ServiceContract] public interface IDealerStockService { [System.ServiceModel.OperationContract] [TransactionFlow(TransactionFlowOption.Mandatory)] void CreateDealerStock(DealerStock dealerStock); } }
service1-
public class DealerStockService:IDealerStockService { private IBLDealerStock blDealerStock; private IBalanceVoucherService iBalanceVoucherService; public DealerStockService() { blDealerStock = DealerStockFactory.CreateDealerStock(); } #region IDealerStockService 成员 [OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)] public void CreateDealerStock(GreatWall.VMS.DealerStock.ServiceContract.DealerStock dealerStock) { Console.Write("service-DealerStock-localidentifier:" + Transaction.Current.TransactionInformation.LocalIdentifier); Console.Write("service-DealerStock-DistributedIdentifier:" + Transaction.Current.TransactionInformation.DistributedIdentifier); BLLContract.DealerStock stock = new BLLContract.DealerStock(); stock.PK = -1; stock.Vin = dealerStock.Vin; stock.Amount = dealerStock.Amount; blDealerStock.SaveDealerStock(stock); } #endregion }
contract2-
namespace GreatWall.VMS.BalanceVoucher.ServiceContract { [System.ServiceModel.ServiceContract] public interface IBalanceVoucherService { [System.ServiceModel.OperationContract] [TransactionFlow(TransactionFlowOption.Mandatory)] void CreateBalanceVoucher(BalanceVoucherEntity entity); } }
service2-
namespace GreatWall.VMS.BalanceVoucher.Service { public class BalanceVoucherService:IBalanceVoucherService { #region IBalanceVoucherService 成员 [OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)] public void CreateBalanceVoucher(ServiceContract.BalanceVoucherEntity entity) { Console.Write("service-DealerStock-localidentifier:" + Transaction.Current.TransactionInformation.LocalIdentifier); Console.Write("service-DealerStock-DistributedIdentifier:" + Transaction.Current.TransactionInformation.DistributedIdentifier); GreatWall.VMS.BalanceVoucher.BLLContract.IBLBalanceVoucher ibl = BalanceVoucherFactory.CreateBalanceVoucher(); BLLContract.BalanceVoucherEntity blEntity = new BLLContract.BalanceVoucherEntity(); blEntity.OccurTime = entity.OccurTime; blEntity.VoucherID = entity.VoucherID; ibl.CreateBalanceVoucher(blEntity); } #endregion } }
servicehost-config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="GreatWall.VMS.DealerStock.Service.DealerStockService" behaviorConfiguration="DealerStockServiceBehavior"> <endpoint address="http://localhost:8888/DealerStock" binding="wsHttpBinding" bindingConfiguration="wsTransitactionBinding" contract="GreatWall.VMS.DealerStock.ServiceContract.IDealerStockService"></endpoint> </service> <service name="GreatWall.VMS.BalanceVoucher.Service.BalanceVoucherService" behaviorConfiguration="BalanceVoucherServiceBehavior"> <endpoint address="http://localhost:8887/BalanceVoucher" binding="wsHttpBinding" bindingConfiguration="wsTransitactionBinding" contract="GreatWall.VMS.BalanceVoucher.ServiceContract.IBalanceVoucherService"></endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="DealerStockServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8888/DealerStock/mex"/> </behavior> <behavior name="BalanceVoucherServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8887/BalanceVoucher/mex"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="wsTransitactionBinding" transactionFlow="true"> </binding> </wsHttpBinding> </bindings> </system.serviceModel> </configuration>
servicehost-
namespace GreatWall.VMS.ServiceHost { class Program { static void Main(string[] args) { System.ServiceModel.ServiceHost hostForDealerStock = new System.ServiceModel.ServiceHost(typeof(DealerStock.Service.DealerStockService)); System.ServiceModel.ServiceHost hostForBalanceVoucher = new System.ServiceModel.ServiceHost(typeof(GreatWall.VMS.BalanceVoucher.Service.BalanceVoucherService)); try { hostForDealerStock.Open(); hostForBalanceVoucher.Open(); Console.Write("服务已经启动"); Console.Read(); } catch(Exception ex) { hostForDealerStock.Abort(); hostForBalanceVoucher.Abort(); throw ex; } finally { hostForDealerStock.Close(); hostForBalanceVoucher.Close(); } } } }
client
private void btnCommit_Click(object sender, EventArgs e) { SRDealerStock.DealerStockServiceClient client = new SRDealerStock.DealerStockServiceClient(); SRBalanceVoucher.BalanceVoucherServiceClient clientForBalanceVoucher = new SRBalanceVoucher.BalanceVoucherServiceClient(); SRDealerStock.DealerStock dealerStock = new SRDealerStock.DealerStock(); dealerStock.Amount =int.Parse(this.tbAmount.Text); dealerStock.Vin = this.tbVin.Text; SRBalanceVoucher.BalanceVoucherEntity balanceVoucherEntity = new SRBalanceVoucher.BalanceVoucherEntity(); balanceVoucherEntity.OccurTime = DateTime.Now; balanceVoucherEntity.VoucherID = this.tbBalanceVoucher.Text; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew)) { try { Console.Write("client-localidentifier:" + Transaction.Current.TransactionInformation.LocalIdentifier); Console.Write("client-DistributedIdentifier:" + Transaction.Current.TransactionInformation.DistributedIdentifier); client.CreateDealerStock(dealerStock); clientForBalanceVoucher.CreateBalanceVoucher(balanceVoucherEntity); scope.Complete(); MessageBox.Show("创建成功!"); } catch (Exception ex) { throw ex; MessageBox.Show("创建失败!"); } } }
clientconfig
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IDealerStockService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="true" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> <binding name="WSHttpBinding_IBalanceVoucherService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="true" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> <binding name="" /> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:8887/BalanceVoucher" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IBalanceVoucherService" contract="SRBalanceVoucher.IBalanceVoucherService" name="WSHttpBinding_IBalanceVoucherService"> <identity> <userPrincipalName value="lizhch@GREATWALL.LOCAL" /> </identity> </endpoint> <endpoint address="http://localhost:8888/DealerStock" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDealerStockService" contract="SRDealerStock.IDealerStockService" name="WSHttpBinding_IDealerStockService"> <identity> <userPrincipalName value="lizhch@GREATWALL.LOCAL" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>