数据访问模式:数据并发控制(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" ...
随机推荐
- .net之微信企业号开发(二) 企业号人员身份认证与开发
前言 这里完全可以链接一个登录页面,让用户输入用户名密码进行登录的...2333 但是,这样所就完全失去了微信企业号的意义,本来进入微信企业号的时候,就已经对人员身份进行认证了,你这里再让别人登录,不 ...
- 如何利用word2013写图文并茂的博客
我有一天心血来潮,突然想写博客了,由于是技术贴,图文并茂,多图预警,可是在新浪博客,网易博客,博客园这些博客上写技术贴,似乎都不支持从已经写好的word文档里粘贴过去,于是各种百度各种尝试各种摸索 ...
- WCF服务配置问题
上一篇中,我们主要是使用了代码来实现服务的自我寄宿.代码的实现稍微复杂些,不过还有些使用配置文件和配置工具的方法.下面来一一介绍下. 1.配置文件.首先在Host下添加个app.confi ...
- VHDL生成的ngc文件被verilog的工程调用的问题
1. 问题的提出 工程a是一个soft core,用VHDL写的,综合的时候去掉了"Add I/O buffers" ,并将-iob(Pack I/O Registers into ...
- 如何判断ScrollView滑动方形
1/判断滚动视图左右滚动 { CGFloat startContentOffsetX;//滚动开始的坐标 CGFloat willEndContentOffsetX; //滚动即将停止的坐标 CGFl ...
- 关于IDW空间插值
空间插值一般都会用到IInterPolationOP接口等 首先是通过图层的名称获取图层的方法: private ILayer GetLayerByName(string name) { ...
- jQuery给标签写入内容
使用原生js时可以用 document.getElementById("divID").innerHTML = "div的显示值" 来赋值: 而在使用jQuer ...
- Manifesto of the Communist Party
A spectre is haunting Europe – the spectre of communism. All the powers of old Europe have entered i ...
- CodeIgniter2.2.0-在控制器里调用load失败报错的问题
报错如下: hello A PHP Error was encountered Severity: Notice Message: Undefined property: Test::$load Fi ...
- 【腾讯Bugly干货分享】从0到1打造直播 App
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d42e7fd6ec467453bf58 作者:李智文 概要 分享内容: ...