数据访问模式:数据并发控制(Data Concurrency Control)
1.数据并发控制(Data Concurrency Control)简介
数据并发控制(Data Concurrency Control)是用来处理在同一时刻对被持久化的业务对象进行多次修改的系统。当多个用户修改业务对象的状态并试图并发地将其持久化到数据库时,需要一种机制来确保一个用户不会对另一个并发用户的事务状态造成负面影响。
有两种形式的并发控制:乐观和悲观。乐观并发控制假设当多个用户对业务对象的状态同时进行修改时不会造成任何问题,也称为最晚修改生效(last change wins)。对于一些系统,这是合理的行为。但如果业务对象的状态需要与从数据库中取出的状态保持一致,就需要悲观并发控制。
悲观并发控制可以有多中风格,可以在检索出记录后锁定数据表,也可以保存业务对象原始内容的副本,然后再进行更新之前将该副本与数据存储中的版本进行比对。确保在这次事务期间没有对该记录进行修改。
2.数据并发控制的实现示例
常用的数据并发控制实现方式有两种:数据库实现及代码控制实现。悲观并发控制在数据库实现方面可以有加入数据库锁机制,代码控制实现方面可以增加一个保存版本号字段,用于版本之间的对比。使用版本号来检查在业务实体从数据库中检索出之后是否被修改。更新时,把业务实体的版本号与数据库中的版本号进行比对之后再提交修改。这样确保业务实体在被检索出后没有被修改。
使用版本号来实现悲观并发控制的方式,其中的版本号可以使用数据库中提供的数据类型timestamp或代码中控制管理版本。数据库timestamp类型字段在每一次update操作均会生成新值。
1>、timestamp版本控制
SQL Server中timestamp类型对应C#的byte[]类型,timestamp字段值为byte[8]。
2>、程序代码实现版本控制
代码结构:
EntityBase.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataAccessPatterns.DataConcurrencyControl.Model
{
public abstract class EntityBase
{
public Guid Version { get; set; }
}
}
Person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataAccessPatterns.DataConcurrencyControl.Model
{
public class Person : EntityBase
{
public Guid ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
IPersonRepository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using DataAccessPatterns.DataConcurrencyControl.Model; namespace DataAccessPatterns.DataConcurrencyControl.Repository
{
public interface IPersonRepository
{
void Add(Person person);
void Save(Person person);
Person FindBy(Guid id);
}
}
PersonRepository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using DataAccessPatterns.DataConcurrencyControl.Model; namespace DataAccessPatterns.DataConcurrencyControl.Repository
{
public class PersonRepository : IPersonRepository
{
public void Add(Person person)
{
using (var context = new DataAccessPatternsContext())
{
context.Persons.Add(person);
context.SaveChanges();
}
} public void Save(Person person)
{
// person.Version为获取出来的上一次版本,Version字段值保持获取出来时字段值。
string strSql = String.Format(@"UPDATE dbo.Person SET FirstName='{0}',LastName='{1}' WHERE ID='{3}' AND Version='{4}'", person.FirstName, person.LastName, person.ID, person.Version);
using (var context = new DataAccessPatternsContext())
{
int affectedRows = context.Database.ExecuteSqlCommand(strSql, null); if (affectedRows == )
{
throw new ApplicationException(@"No changes were made to Person ID (" + person.ID + "), this was due to another process updating the data.");
}
else
{
// person.Version赋予新值用于下一次版本对比
person.Version = Guid.NewGuid();
}
}
} public Person FindBy(Guid id)
{
using (var context = new DataAccessPatternsContext())
{
return context.Persons.Find(id) as Person;
}
}
}
}
数据访问模式:数据并发控制(Data Concurrency Control)的更多相关文章
- android数据访问模式:档、SharedPreferences
android数据访问模式:档.SharedPreferences.SQLite 数据库.Content provider 文件流: 使用java IO流对文件进行读写操作,文件权限默认. 指定文件权 ...
- 数据访问模式之Repository模式
数据访问模式之Repository模式 数据访问层无非就是对数据进行增删改查,其中增.删.改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子 ...
- XAF-列表视图数据访问模式
本主题介绍有关列表视图如何提供数据访问的几种方式.请注意,选择正确的方式对于实现XAF应用程序的最佳性能至关重要. 数据访问模式概述 在模型编辑器中,通过 视图-> <ListV ...
- 在PHP系统里连接MySQL 数据访问,+ + + + + 数据删除
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 数据访问模式:Identity Map(标识映射)模式
1.Identity Map模式简介 Identity Map(标识映射)模式是通过将所有已加载对象放在一个映射中确保所有对象只被加载一次,并且在引用这些对象时使用该映射来查找对象.在处理数据并发访问 ...
- 从武侠中的兵器看待数据访问工具——Hibernate Spring.Data Mybatis
<泪痕剑>第31集,卓爷大谈自己的兵器,我从中摘录,觉得非常受用. “你错了,我们和武器之间的关系,就好像选择情人一样,不管是否擅长,都要用感情. 我少年时候用刀,青年时候仍用刀,不知道用 ...
- MySQL 的乐观并发控制Optimistic concurrency control
默认情况下, MySQL的Innodb事务隔离级别是重复读 repeatable read, SELECT @@GLOBAL.tx_isolation, @@tx_isolation;REPEATAB ...
- MYSQLi数据访问查询数据
单条件查询 <body> <div align="center" style="width:90%;"> <h1>数据查询& ...
- MYSQLi数据访问修改数据
<link href="../bootstrap.min.css" rel="stylesheet" type="text/css" ...
随机推荐
- 初学python第二天
今天我将用python来编写一款小游戏,用这个来总结一下自己学过的一些基础语法.没错,它就是井字游戏.想想自己第一接触这种游戏,还是小学生呢
- [转]C语言指针学习经验总结浅谈
指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...
- 读《我是IT小小鸟》后有感
我是一名大一新生,在下半学期开学时,我迎来新课程——<大学生职业生涯规划与就业指导 >.这是一门既新颖,又有许多就业知识和理论的学科.在课上,老师向我们推荐了一本书,名叫<我是IT小 ...
- Restful.Data v1.0 - 轻量级数据持久层组件, 正式开源发布了
经过几个星期的优化调整,今天 Restful.Data 正式开源发布. 源码地址:https://github.com/linli8/Restful 今天不写那么多废话了,还是重新介绍一下 Restf ...
- MySQL4:存储过程和函数
什么是存储过程 简单说,存储过程就是一条或多条SQL语句的集合,可视为批文件,但是起作用不仅限于批处理.本文主要讲解如何创建存储过程和存储函数以及变量的使用,如何调用.查看.修改.删除存储过程和存储函 ...
- 站在移动互联时代的十字路口上_deviceone
最近总能看到类似“App已死,服务永生”.“App必死,web永生” .“App已死,微信建站已生”这样的文章.不晓得这些网络写手到底是想代表某些公司的立场.还是想要表达怎么样的一个情结,文章中语气都 ...
- 目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点?以及Github的注册过程
一.目前流行的源程序版本管理软件和项目管理软件有Microsoft TFS.GitHub.SVN.Coding等. 二.各有什么优缺点 三.在GitHub注册账户的过程 Microsoft TFS的优 ...
- 渣渣小本求职复习之路每天一博客系列——TCP/IP协议栈(5)
前情回顾:一篇短短的博客明显不能满足TCP和UDP这两个饥渴的汉子,而且还被应用协议占了一小半的篇幅.在昨天结束之后,相信大家都基本对TCP/IP协议栈的轮廓有一个大概的印象了,能够对整体有所把握. ...
- [ACM_几何] Fishnet
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28417#problem/C 本题大意:有一个1X1的矩形,每边按照从小到大的顺序给n ...
- C#开源磁盘/内存缓存引擎
前言 昨天写了个 <基于STSdb和fastJson的磁盘/内存缓存>,大家可以先看看.下午用到业务系统时候,觉得可以改进一下,昨晚想了一个晚上,刚才重新实现一下. 更新 1. 增加了对批 ...