数据访问模式:数据并发控制(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学习之路-Day2
数据类型常用操作 不管是查整数还是查布尔或者是列表...要记住 dir(int) 查看某个类型的功能 help(int) 查看该类型的功能及文档说明 type(4) 查看某个字符或数字的类型- ...
- Alamofire源码学习
Core文件夹: Alamofire.swift - - - 该文件中主要是给用户提供一些便利的调用方法,用户可以直接调用该文件中的便利方法来使用Alamofire相关功能. ...
- Android 抗锯齿的两种方法
Android 抗锯齿的两种方法 (其一:paint.setAntiAlias(ture);paint.setBitmapFilter(true)) 在Android中,目前,我知道有两种出现锯齿 ...
- MYSQL删除表的记录后如何使ID从1开始
MYSQL删除表的记录后如何使ID从1开始 MYSQL删除表的记录后如何使ID从1开始 http://hi.baidu.com/289766516/blog/item/a3f85500556e2c09 ...
- Linux内核--网络栈实现分析(五)--传输层之UDP协议(上)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7532512 更多请看专栏, ...
- haproxy的使用
假如 www.example.com想要使用haproxy作为代理,则要在自己的 dns服务器设置AAAA记录对应于haproxy机器的IP. 这样访问www.example.com其实就访问了hap ...
- 读《我是IT小小鸟》后有感
我是一名大一新生,在下半学期开学时,我迎来新课程——<大学生职业生涯规划与就业指导 >.这是一门既新颖,又有许多就业知识和理论的学科.在课上,老师向我们推荐了一本书,名叫<我是IT小 ...
- 强大好用的"文本"编辑器
1 editplugs 说明:EditPlus是一款由韩国 Sangil Kim (ES-Computing)出品的小巧但是功能强大的可处理文本.HTML和程序语言的Windows编辑器,你甚至可以通 ...
- .Net平台下,分布式文件存储的实现
遇到的问题 对于Web程序,使用一台服务器的时候,客户端上传的文件一般也都是存储在这台服务器上.但在集群环境中就行不通了,如果每个服务器都存储自己接受到的文件,就乱套了,数据库中明明有这个附件的记录, ...
- ng-template寄宿方式
如果你是一个angular的开发者的话,对于ng-html2js你应该 很熟悉.对于angular的指令,我们经常需要定义模板( directive template/templateUrl),你可以 ...