wcf系列学习5天速成——事务的使用

 

摘抄自:http://www.cnblogs.com/huangxincheng/archive/2011/11/06/2238273.html

事务简单的一句话介绍:顺利执行就录入到数据库,如果中途出现异常就回滚到初始值,确保数据的正确性和防止冗余

在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们要插入两张表,User和Shop表。

当然要补录入成功,要不全失败

先晒项目结构:

第二步: 新建newdata数据库,用EF去映射,然后新建serviceWCF类库

这里有一点需要注意,在确保数据的正确性的同时,必须要保证数据库映射类型一样:

第三步:新建一个Model类库。建立两个实体类Shop和User,当然自定义类型在WCF中传输,

           必须在类上加上【DataContract】,属性上加【DataMember】。

第四步:然后在ServiceWCF类库中新建两个文件Seller.cs 和 ISeller.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace TransactionWcf
{
public class Seller : ISeller
{
public bool Add(Model.User user, out int userID)
{
using (NewDataEntities db = new NewDataEntities())
{
try
{
User userModel = new User()
{
UserName = user.UserName,
Passwrod = user.Password
};
db.AddToUser(userModel);
db.SaveChanges();

userID = userModel.UserID;
return true;
}
catch (Exception)
{
userID = 0;
throw;
}
}
}

public bool Add(Model.Shop shop, out int shopID)
{
using (NewDataEntities db = new NewDataEntities())
{
try
{
Shop shopModel = new Shop()
{
ShopName = shop.ShopName,
ShopUrl = shop.ShopUrl,
UserID = shop.UserID
};
db.AddToShop(shopModel);
db.SaveChanges();
shopID = shopModel.ShopID;
return true;
}
catch (Exception)
{
shopID = 0;
throw;
}
}
}

///<summary>
/// 录入用户和商店
///</summary>
///<param name="user"></param>
///<param name="shop"></param>
///<returns></returns>
//TransactionScopeRequired=true 告诉serviceHost自托管服务,进入我的方法,必须给我加上事务
//TransactionAutoComplete方法执行中,如果没有抛出异常,则自动提交
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
public bool Add(Model.User user, Model.Shop shop)
{
int shopID;
int UserID;
//注意,这个方法操作了两个数据实例,为addUser和addShop。所以晋升为分布式服务
if (Add(user, out UserID))
{
//注意注意,我在Adduser成功的情况下,抛出异常,看是否回滚。
throw new Exception();

shop.UserID = UserID;
return Add(shop, out shopID);
}
return false;
}
}
}

第五步: 新建Host来承载了,配置AppConfig,这些细节就不再说了。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>

<behaviors>
<serviceBehaviors>
<behavior name="Host.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service
behaviorConfiguration="Host.Service1Behavior"
name="TransactionWcf.Seller">
<endpoint address=""
binding="wsHttpBinding"
contract="TransactionWcf.ISeller">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/ISeller/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<connectionStrings>
<add name="NewDataEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=WUXUELEI\SQLEXPRESS;Initial Catalog=NewData;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>

承载服务:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(TransactionWcf.Seller)))
{

host.Opened += delegate
{
Console.WriteLine("wcf服务已经启动");
};
host.Open(); //开启服务
Console.ReadLine();
}
}
}
}


至此我们的服务端已经建立好了...先用wcftestclient测试下试试看:

好,下面建立客户端:

第六步:开启WCF服务,新建ServiceClient类库,然后用信道生成实例。

先添加服务引用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace ServiceClient
{
class Program
{
static void Main(string[] args)
{
//创建实例对象
var user = new ServiceIsell.User()
{
UserName="huaying520",
Password="I Can Fly"
};
var shop = new ServiceIsell.Shop()
{
ShopName="小吴的店铺",
ShopUrl="http://www.baidu.com"
};

var factory = new ChannelFactory<ServiceIsell.ISellerChannel>(new WSHttpBinding(),new EndpointAddress("http://localhost:8732/Design_Time_Addresses/ISeller/")); //先创建信道
var client = factory.CreateChannel(); //创建客户端

if (client.Add(user, shop))
{
Console.WriteLine("您的店铺已经成功录入");
}
else
{
Console.WriteLine("不好意思,您的店铺有问题");
}
Console.ReadLine();
}
}
}

最后就是测试了:

    首先:走正常流程。client.Add方法调用服务器端,运行效果如图所示:

是的,数据已经正常插入成功,对Client端而言,这个操作是透明的。

 

  然后:  我们在Seller类中的Add方法中故意加入异常。看效果咋样。

然后运行客户端的时候:

说明是已经检测到咱们新建立的异常了...看数据库有没有新加数据...咱select下:

果然如我所料..此处没有录入新数据...说明咱的事物是成功的!

当然为了确保这个客户端抛出的异常是来自咱新建立的Expection...把客户端bug查看开启:

运行下看看:

呵呵...看到了..就是咱们新建立的new Exception导致的.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值