我们一起学习WCF 第十篇Wcf中实现事务
数据一致性在工作中显得非常重要,有时候我们库中出现脏数据导致程序报错,但是又很难发现这样的错误,所以为了数据的完整性建议在程序中加入事物。
什么是事物:我们都有团队合作吧,比喻团队有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中实现事务的更多相关文章
- [老老实实学WCF] 第十篇 消息通信模式(下) 双工
老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...
- Dubbo学习系列之十五(Seata分布式事务方案TCC模式)
上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...
- 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系
重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...
- Egret入门学习日记 --- 第二十篇(书中 9.1~9.3 节 内容 组件篇)
第二十篇(书中 9.1~9.3 节 内容 组件篇) 第八章中的内容. 以上都是基本的Js知识,我就不录入了. 直接来看 第9章. 开始 9.1节. 以上内容告诉你,Egret官方舍弃了GUI,使用了E ...
- Egret入门学习日记 --- 第十篇(书中 2.9~2.13节 内容)
第十篇(书中 2.9~2.13节 内容) 好的 2.9节 开始! 总结一下重点: 1.之前通过 ImageLoader 类加载图片的方式,改成了 RES.getResByUrl 的方式. 跟着做: 重 ...
- MyCat 学习笔记 第十篇.数据分片 之 ER分片
1 应用场景 这篇来说下mycat中自带的er关系分片,所谓er关系分片即可以理解为有关联关系表之间数据分片.类似于订单主表与订单详情表间的分片存储规则. 本文所说的er分片分为两种: a. 依据主键 ...
- Python学习【第十篇】基础之杂货铺
字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存. 百分号方式: ...
- MySQL学习【第十篇存储引擎实际应用】
一.将现有的myiasm引擎转化为innodb引擎 1.首先我们知道myisam有几点特别烦 a( 运用的是表级锁 b( 不支持csr(故障自动恢复) 2.mysql的5.1.177版本innodb引 ...
- Django学习笔记第十篇--实战练习六--发送邮件
一.发送邮件需要引入的包依赖文件(Django1.8 Python2.7) from django.core.mail import send_mail,send_mass_mail 其中send_m ...
随机推荐
- php memcache分布式和要注意的问题
Memcache的分布式介绍 memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能.服务器端仅包括内存存储功能,其实现非常简单.至于memcached的分布式,则是完全由客户 ...
- 如何在Ubuntu中添加中文输入法
首先打开终端,输入以下命令 打开终端输入以下命令 弹出设置IBus首选项对话框,单击输入法文本框,再单击添加按钮,选中汉语中的拼音,单击添加,设置完毕. 最后单击输入法图标的选项中的首选项中的拼音模式 ...
- ThinkPhp表单令牌和字段映射
开启表单令牌: 先在配置文件目录下定义tags.php 在里面添加 return array( 'view_filter' =>array('Behavior\TokenBuildBehavio ...
- Docker中配置字符集支持中文
在Dockerfile中加入以下内容: ENV LANG en_US.UTF-8ENV LANGUAGE en_US:enENV LC_ALL en_US.UTF-8
- Swift 开发语法
文/Tuberose(简书作者)原文链接:http://www.jianshu.com/p/5e2d4c34f18e著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 简介 Swift 语 ...
- 如何弹出WiFi提示列表。
如果你的程序中用到了WiFi,想在没有有效WiFi的时候出现如图所示的提示该怎么做? 其实很简单, 只需要在Info.plist中添加如下Key/Value UIRequiresPersistentW ...
- System.Reflection 获取描述
我们需要获取类,属性,方法的描述.这个跟获取枚举的描述一样,需要我们通过反射来做.这还需要我们的利用System.ComponentModel:Description 的属性来完成. 新建一个类:使 ...
- Xcode 5.1安装插件:规范凝视生成器VVDocumenter
类似java的多行凝视! 安装过程: 1.前往GitHub下载project文件:VVDocumenter-Xcode 2.用Xcode打开project,Command + B Build成功后,能 ...
- selenium java maven 自动化测试(二) 页面元素获取与操作
在第一节中,我们已经成功打开了页面,但是自动化测试必然包含了表单的填写与按钮的点击. 所以在第二章中我以博客园为例,完成按钮点击,表单填写 还是以代码为准,先上代码: package com.ryan ...
- 基于Python在MacOS上安装robotframework-ride
基于Python在MacOS上安装robotframework-ride https://www.jb51.net/article/153665.htm https://www.jianshu.com ...