我们一起学习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 ...
随机推荐
- 随手练——HDU 1284 动态规划入门
#include <iostream> #include <algorithm> #include <string.h> using namespace std; ...
- 《metasploit渗透测试魔鬼训练营》靶机演练之第五章实战案例KingView 6.53版本CVE-2011-0406漏洞
在一个笔记本上开两个虚拟机有点卡,而且太麻烦,就把metasploit的目标靶机放在别的机器上了,ip自己配置了一下, 目标主机:192.168.137.254 入侵机:192.168.137.253 ...
- java 静态相关内容
一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码 ...
- javascript-对象搜索算法挑战
对象搜索算法挑战 function where(collection, source) { var arr = []; var status = null; // What's in a name? ...
- rocketmq双主发送消息 SLAVE_NOT_AVAILABLE 状态
RocketMQ最佳实践之Producer 投递状态 发送消息时,将得到包含SendStatus的SendResult.首先,我们假设消息的isWaitStoreMsgOK = true(默认是tru ...
- JDK(二)JDK1.8源码分析【排序】timsort
如无特殊说明,文中的代码均是JDK 1.8版本. 在JDK集合框架中描述过,JDK存储一组Object的集合框架是Collection.而针对Collection框架的一组操作集合体是Collecti ...
- unordered_map 遇到 vector subscript out of range 的错误提示
错误类型 当调用unordered_map的函数的时候,会出现如下问题: 使用linux运行则会提示 float exeption(core dump) 原因 遇到vector subscript o ...
- 【Javascript-基础-ecma6】ecma6学习笔记(持续更新)
makdown语法手册API String 新特性的方法 基本不支持IE浏览器 String.fromCodePoint(6特性) String.prototype.codePointAt(6特性) ...
- ueditor getshell漏洞重现及分析
0x00 概述 8月21日,网上爆出ueditor .net版本getshell漏洞,由于只校验ContentType而没校验文件后缀导致getshell. 0x01 漏洞重现 Payload: &l ...
- td内的所有数字格式化保留两位小数
$("td").each(function(i,el){ var td = parseFloat($(el).text()); if(!isNaN(td)){ $(el).text ...