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

什么是事物:我们都有团队合作吧,比喻团队有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. 通过css使文字有渐变的效果

    <style> .color{ background-image: -webkit-gradient(linear, left center, right center, from(rgb ...

  2. easyUi的一些常用方法

    目录: 1.获取表格的pageNumber和pageSize 2.获取/设置下拉列表的选中值 3.下拉列表的输入框的禁用 1.获取表格的pageNumber和pageSize var pageNumb ...

  3. HDU 1686 Oulipo (可重叠匹配 KMP)

    Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  4. nRF5 SDK for Mesh( 七 ) BLE MESH 的 架构(rchitecture)

    The mesh architecture   The mesh stack consists of a number of subsystems that are interfaced throug ...

  5. C#中调用方法

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

  6. 让IIS 7 如同IIS 8 第一次请求不变慢(转载)

    当我们把网站部署在IIS7或IIS6S的时候,每当IIS或是Application Pool重启后,或者站点在长时间没有请求访问后,第一次请求网站反应总是很慢.所以每次网站更新都会给第一个用户带来不好 ...

  7. Angular7教程-04-Angular常用操作(下)

    6. 数据双向绑定 视图和数据,只要一方发生变化,另一方跟着变化. 好处是不需要在代码中手动更新视图,简化开发,增加代码内聚性,代码可读性更强. 缺点是当绑定的数据层次深.数据量大时,会影响性能. 双 ...

  8. js toFixed()方法的坑

    javascript中toFixed使用的是银行家舍入规则. 银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法. 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零 ...

  9. JS-instanceof 与typeof

    通常来讲,使用 instanceof 就是判断一个实例是否属于某种类型 而typeof  无论引用的是什么类型的对象,它都返回 "object" var arr=[1,2,3]; ...

  10. c# 在 websocket 中访问 session

    今天的项目需要用到websocket,但是中websocket中无法直接访问session,一访问session就出错,断开连接. 找了老半天百度也没有相关c#的介绍和方法,没办法,找不到现成的代码, ...