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)的更多相关文章

  1. android数据访问模式:档、SharedPreferences

    android数据访问模式:档.SharedPreferences.SQLite 数据库.Content provider 文件流: 使用java IO流对文件进行读写操作,文件权限默认. 指定文件权 ...

  2. 数据访问模式之Repository模式

    数据访问模式之Repository模式   数据访问层无非就是对数据进行增删改查,其中增.删.改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子 ...

  3. XAF-列表视图数据访问模式

    本主题介绍有关列表视图如何提供数据访问的几种方式.请注意,选择正确的方式对于实现XAF应用程序的最佳性能至关重要.    数据访问模式概述   在模型编辑器中,通过 视图-> <ListV ...

  4. 在PHP系统里连接MySQL 数据访问,+ + + + + 数据删除

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 数据访问模式:Identity Map(标识映射)模式

    1.Identity Map模式简介 Identity Map(标识映射)模式是通过将所有已加载对象放在一个映射中确保所有对象只被加载一次,并且在引用这些对象时使用该映射来查找对象.在处理数据并发访问 ...

  6. 从武侠中的兵器看待数据访问工具——Hibernate Spring.Data Mybatis

    <泪痕剑>第31集,卓爷大谈自己的兵器,我从中摘录,觉得非常受用. “你错了,我们和武器之间的关系,就好像选择情人一样,不管是否擅长,都要用感情. 我少年时候用刀,青年时候仍用刀,不知道用 ...

  7. MySQL 的乐观并发控制Optimistic concurrency control

    默认情况下, MySQL的Innodb事务隔离级别是重复读 repeatable read, SELECT @@GLOBAL.tx_isolation, @@tx_isolation;REPEATAB ...

  8. MYSQLi数据访问查询数据

    单条件查询 <body> <div align="center" style="width:90%;"> <h1>数据查询& ...

  9. MYSQLi数据访问修改数据

    <link href="../bootstrap.min.css" rel="stylesheet" type="text/css" ...

随机推荐

  1. 尝试u3d中将代码与编辑器分离

    最近与朋友交流,他一直是做端游,最近接触了u3d以后无法忍受代码与配置文件,美术资源全部纠缠在一起的状况,于是一直在琢磨怎么将编辑器与代码彻底分离. 自己也抽空研究一下,碰到一些问题先记录下来. 首先 ...

  2. SAS 画折线图PROC GPLOT

    虽然最后做成PPT里的图表会被要求用EXCEL画,但当我们只是在分析的过程中,想看看数据的走势,直接在SAS里画会比EXCEL画便捷的多. 修改起来也会更加的简单,,不用不断的修改程序然后刷新EXCE ...

  3. 用sql取出来的list需要处理成map的两种情况

    1. 原生sql: select a.id,a.name from a SQLQuery sqlQuery=this.getSession().createSQLQuery(sb.toString() ...

  4. poj 1702 三进制问题

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3906   Accepted: 1924 Description Eva h ...

  5. 二进制求最大公约数&&输出二进制

    Divided Land Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  6. 超链接标签a样式生效,取消下划线,文字垂直(上下)居中

    直接设置超链接标签a的属性时并不会生效, 需要将display属性改为inline-block, 即style="display:inline-block" 添加标签a时,默认是有 ...

  7. CSharpGL(40)一种极其简单的半透明渲染方法

    CSharpGL(40)一种极其简单的半透明渲染方法 开始 这里介绍一个实现半透明渲染效果的方法.此方法极其简单,不拖累渲染速度,但是不能适用所有的情况. 如下图所示,可以让包围盒显示为半透明效果. ...

  8. Replication的犄角旮旯(九)-- sp_setsubscriptionxactseqno,赋予订阅活力的工具

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  9. 使用Ant自动化我们的java项目生成

    现在我们已经了解如何定义属性.依赖关系以及如何运行ant,接下来我们将学习怎样使用ant编译java源代码并生成jar文件. 编译源代码 由于Ant的主要目标就是生成java应用程序,它内置了java ...

  10. 不写1行代码,在Mac上体验ASP.NET 5的最简单方法

    昨天微软发布了ASP.NET 5 beta2(详见ASP.NET 5 Beta2 发布),对ASP.NET 5的好奇心又被激发了. 今天下午在Mac OS X上体验了一下ASP.NET 5,而且借助Y ...