数据一致性在工作中显得非常重要,有时候我们库中出现脏数据导致程序报错,但是又很难发现这样的错误,所以为了数据的完整性建议在程序中加入事物。

什么是事物:我们都有团队合作吧,比喻团队有3个人,a负责设计,b负责前端,c负责后台,那么他们三个就是一个整体,哪一个人那里出了问题就要被打回。

第一步:我们开始定义个一个接口

[ServiceContract]
public interface IUserInfo {
[OperationContract]
int AddInfo();
}

第二步当然是实现接口了。这个AddInfo需要添加用户和文章

//使用隐式事务,并把TransactionFlowOption设置为Allowed打开事务流
[OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
[TransactionFlow(TransactionFlowOption.Allowed)]
public int AddInfo()
{
using (TransactionScope transcope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
try
{
if (AddUser())
{
if (!AddArticle())
{
Transaction.Current.Rollback();
return ;
}
else {
transcope.Complete();
return ;
}
}
else {
Transaction.Current.Rollback();
}
}
catch (Exception ep)
{
Transaction.Current.Rollback();
return ;
}
return ;
}
}
/// <summary>
/// 添加用户
/// </summary>
/// <returns></returns>
public bool AddUser() {
try {
string guid = System.Guid.NewGuid().ToString();
string userName = "zhangsan";
string realName = "张三";
DateTime dateTime = DateTime.Now;
string sql = "insert into MyUser(Id,UserName,RealName,SysDate)values(@Id,@UserName,@RealName,@SysDate)";
SqlParameter[] param = new SqlParameter[]
{
new SqlParameter("@Id",guid),
new SqlParameter("@UserName",userName),
new SqlParameter("@RealName",realName),
new SqlParameter("@SysDate",dateTime)
};
string Conn = ConfigurationManager.ConnectionStrings["dbLink"].ConnectionString;
return SqlHelper.ExecuteNonQuery(Conn, CommandType.Text, sql, param) > ;
}
catch (Exception) {
return false;
}
}
/// <summary>
/// 文献信息
/// </summary>
/// <returns></returns>
public bool AddArticle() {
try {
string guid = System.Guid.NewGuid().ToString();
string Title = null;
string Content = "我在测试";
DateTime dateTime = DateTime.Now;
string sql = "insert into Info(Id,Title,Content,SysDate)values(@Id,@Title,@Content,@SysDate)";
SqlParameter[] param = new SqlParameter[]
{
new SqlParameter("@Id",guid),
new SqlParameter("@Title",Title),
new SqlParameter("@Content",Content),
new SqlParameter("@SysDate",dateTime)
};
string Conn = ConfigurationManager.ConnectionStrings["dbLink"].ConnectionString;
return SqlHelper.ExecuteNonQuery(Conn, CommandType.Text, sql, param) > ;
}
catch (Exception ep)
{
return false;
}
}

注释1:TransactionAutoComplete=true的时候表示没有异常的时候自动完成事物范围

第三步:显得方法AddArticle()添加不进去库,我在数据库中不准为null,看下单元测试

public void AddInfoTest()
{
UserInfoClient.UserInfoClient userInfo=new UserInfoClient.UserInfoClient();
int result = userInfo.AddInfo();
Assert.AreEqual(, result);
}

效果:

第四步:说明事物我们实现了,但是很多时候我们都是和别的部门或者调用别人的wcf所以需要如果其中任何一方数据出现错误就要需要回滚现在我们开始写第二个wcf接口

接口同上,现在看下方法

public class User : IUser {
//使用隐式事务,并把TransactionFlowOption设置为Allowed打开事务流
[OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
[TransactionFlow(TransactionFlowOption.Allowed)]
public int AddInfo() {
Client.UserInfoClient userInfoClient = new UserInfoClient();
using (TransactionScope transcope = new TransactionScope(TransactionScopeOption.RequiresNew)) {
try {
if (!AddUser()) {
Transaction.Current.Rollback();
return ;
}
if (!AddArticle()) {
Transaction.Current.Rollback();
return ;
}
if (userInfoClient.AddInfo() != ) {
Transaction.Current.Rollback();
return ;
}
else {
transcope.Complete();
return ;
}
}
catch (Exception) {
Transaction.Current.Rollback();
userInfoClient.Close();
return ;
}
}

其中调用的AddUser()和AddArticle()同上面一样(这里仅仅为了测试)userInfoClient.AddInfo()这是上一个wcf部署以后的方法

现在我们先看都成功都添加成功(此时成功添加数据库)

[Test]
public void AddInfoTwoTest()
{
Client.UserClient userClient =new UserClient();
Assert.AreEqual(, userClient.AddInfo());
}

效果:

再看第一个wcf添加失败第二个回滚的效果

        /// <summary>
/// 测试回滚
/// </summary>
[Test]
public void AddInfoFailTest()
{
Client.UserClient userClient = new UserClient();
Assert.AreEqual(, userClient.AddInfo());
}

总结:在我们一条数据插入多个表中,或者数据之间有很强的联系,我们可以考虑用事物老保证数据一致性,但是一定注意记得事物要提交,否则可能会出席死锁。大家可以动手试试

源码下载

我们一起学习WCF 第十篇Wcf中实现事务的更多相关文章

  1. [老老实实学WCF] 第十篇 消息通信模式(下) 双工

    老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...

  2. Dubbo学习系列之十五(Seata分布式事务方案TCC模式)

    上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...

  3. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  4. Egret入门学习日记 --- 第二十篇(书中 9.1~9.3 节 内容 组件篇)

    第二十篇(书中 9.1~9.3 节 内容 组件篇) 第八章中的内容. 以上都是基本的Js知识,我就不录入了. 直接来看 第9章. 开始 9.1节. 以上内容告诉你,Egret官方舍弃了GUI,使用了E ...

  5. Egret入门学习日记 --- 第十篇(书中 2.9~2.13节 内容)

    第十篇(书中 2.9~2.13节 内容) 好的 2.9节 开始! 总结一下重点: 1.之前通过 ImageLoader 类加载图片的方式,改成了 RES.getResByUrl 的方式. 跟着做: 重 ...

  6. MyCat 学习笔记 第十篇.数据分片 之 ER分片

    1 应用场景 这篇来说下mycat中自带的er关系分片,所谓er关系分片即可以理解为有关联关系表之间数据分片.类似于订单主表与订单详情表间的分片存储规则. 本文所说的er分片分为两种: a. 依据主键 ...

  7. Python学习【第十篇】基础之杂货铺

    字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存. 百分号方式: ...

  8. MySQL学习【第十篇存储引擎实际应用】

    一.将现有的myiasm引擎转化为innodb引擎 1.首先我们知道myisam有几点特别烦 a( 运用的是表级锁 b( 不支持csr(故障自动恢复) 2.mysql的5.1.177版本innodb引 ...

  9. Django学习笔记第十篇--实战练习六--发送邮件

    一.发送邮件需要引入的包依赖文件(Django1.8 Python2.7) from django.core.mail import send_mail,send_mass_mail 其中send_m ...

随机推荐

  1. Emgu学习之(五)——图像模糊处理

    Visual Studio Community 2015 工程和代码:http://pan.baidu.com/s/1Qia0Q 内容 在这篇文章中将提到以下内容: 中值模糊 高斯模糊 图像模糊能有效 ...

  2. POJ 2299 Ultra-QuickSort 求逆序数 (归并或者数状数组)此题为树状数组入门题!!!

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 70674   Accepted: 26538 ...

  3. mint-ui 企业微信PC端内置浏览器 Picker 无法滚动

    处理 在主JS代码之上附加以下代码 : <script> if (~navigator.userAgent.toLowerCase().indexOf('windowswechat')) ...

  4. android学习:Android上面部署Apache FTPServer

    经过了几天的研究,终于Apache FTPServer在Android的配置和使用上有了一些心得,现在分享出来,提供给大家参考,说到这儿又不得不吐槽一下这要命的转载了,找Apache FTPServe ...

  5. [iOS]CIFilter滤镜

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...

  6. fail2ban 防暴力破解总结

    公司服务器安全问题一直是个令人头疼的问题,许多运维的小伙伴一直在用脚本来监控服务器登录状态,然而脚本编写比较麻烦,今天就给大家推荐一款小而精致的防暴力破解工具 fail2ban ,他可以监控系统日志, ...

  7. NFS网络文件系统

    FFS服务端概述 NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS: NFS允许一个系统在网络上与他人共享目录 ...

  8. HTML5纯Web前端也能开发直播,不用开发服务器(使用face2face)

    前段时间转载了某位大神的一篇文章,开发Web版一对一远程直播教室只需30分钟 - 使用face2face网络教室.非常有意思.看起来非常简单,但作为一名前端开发人员来说,还是有难度.因为要开发服务器端 ...

  9. HTML5视频播放练习:鼠标经过视频播放,鼠标移除停止播放,再次经过继续播放。

    随着HTML5的广泛应用,在一些网站中,经常看到有些预览的短视频预览,鼠标经过就会播放,移除就会停止播放,再次移进去就会继续播放. 自己也研究着做一个比较简单的类似的练习. 视频可以自己到包图网下载, ...

  10. 搭建Jenkins自动化持续构建和部署系统

    什么是Jenkins? Jenkins是一个持续集成和持续交付的java应用程序,可以处理任何类型的构建或持续集成.集成Jenkins可以用于一些测试和部署技术.简单得说就是一款自动化构建测试和部署的 ...