NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译

时间:2022-09-19 23:39:43

NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译

 

第一章第二节Mapping a class with XML
第一章第三节Creating class hierarchy mappings第一章第四节Mapping a one-to-many relationship第一章第五节Setting up a base entity class

Handling versioning and concurrency

版本控制和并发

在任何的多用户操作的系统中,为了处理并发更新以及版本问题,你必须在乐观并发控制和悲观并发控制中选择一种处理方式。在这一节中,我将给你展示怎样使用NHibernate去恰当地处理版本和乐观并发问题

准备工作

完成前面几节中的任务,包括Setting up a base entity class这节

如果去做

1.在Entity基类中,增加一个Version属性,代码如下所示:

 
public abstract class Entity<TId>
{
public virtual TId Id { get; protected set; }
protected virtual int Version { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
 

2.在Product的映射文件中,增加version元素节点,name对应属性名称,代码如下所示:

<natural-id mutable="true">
<property name="Name" not-null="true" />
</natural-id>
<version name="Version" />
<property name="Description" />
<property name="UnitPrice" not-null="true" />

3. 在ActorRole映射文件中,也增加version元素节点

<id name="Id">
<generator class="guid.comb" />
</id>
<version name="Version" />
<property name="Actor" not-null="true" />
<property name="Role" not-null="true" />

分析原理

  假如你有一个同时有两个用户操作数据库的应用程序,用户1和用户2同时获取相同的数据显示在他们的屏幕上,并且开始修改数据,用户1提交了他的修改后的数据至数据库中,一会儿,用户2也提交了他的修改后的数据。如果没有任何的并发访问检查,那么用户2的更新将会在不知不觉中覆盖了用户1的更新。这里有两个办法来防止这种情况的发生:乐观并发控制和悲观并发控制。

  乐观并发控制的处理过程是这样的:当修改后的数据提交的时候,首先检查该数据是否已经被更新过。就上面的场景的来说,用户1和用户2开始修改他们的数据,用户1提交了他的修改后的数据,当用户2也提交了修改后的数据后,他的更新会是失败的,因为此时数据库中的该数据已经和用户2最初取得显示在屏幕上的数据已经不一致了。

下面的示例所示,我们有一个version字段来为一个实体跟踪这个更新的数据,Update如下所示:

 
UPDATE Product
SET Version = 2 /* @p0 */,
Name = 'Junk' /* @p1 */,
Description = 'Cool' /* @p2 */,
UnitPrice = 100 /* @p3 */
WHERE Id = '764de11e-1fd0-491e-8158-9db8015f9be5' /* @p4 */
AND Version = 1 /* @p5 */
 

NHibernate检查这个version的值是否和实体从数据库中加载数据时候的值是相同的,然后为该值加1,如果实体已经被更新过了,那么version字段的值不为1,并且该Update语句将不会更新任何行,NHibernate检测到该语句的更新结果返回的是0行记录就会抛出一个StaleStateException异常,意味着该实体的数据在内存中是过时的,不是最新的,已经和数据库失去了同步了。

补充知识

  乐观并发控制之外的另一个选择就是使用悲观锁定。悲观锁定的过程是这样的:当一个用户获取数据的时候就给该数据加上一个独占锁,并且在他编辑该数据的时候也始终加上该独占锁,这样当用户1把数据显示在屏幕上进行编辑的时候,用户2就无法再获取同样的数据显示在屏幕上了。在上面的场景中,用户1取得数据,然后他拥有了对该数据的独占锁,用户2就无法再从数据库中读取该数据了。用户2的查询被阻塞,直至用户1释放了该独占锁或者查询超时。用户1在修改数据的时候不可避免地会有接听一个电话或者走开喝一杯咖啡的情况,这样的话将严重影响系统的并发访问。为了实现上述的悲观锁定,NHibernate需要你在应用程序事务中使用session.Lock。

乐观并发控制的其他方法

  除了使用整形类型的version字段以外,NHibernate同样也允许我们使用基于DateTime类型的version字段。然而,Micorosoft SQL Server的datetime类型的精度为3毫秒,如果两个更新的提交非常的接近的话就会有问题了。最好是使用SQL Server 2008的 DateTime2日期类型,它拥有高达100纳秒的时间精度,或者也可以使用timestamp日期类型。

NHibernate也允许你使用传统的乐观并发控制的方式,可以通过设置optimistic-lock属性为dirty来实现,一个简单的示例看起来如下:

<class name="Product"
dynamic-update="true"
optimistic-lock="dirty">

在这种情况下,把Product对象的name从Stuff修改为Junk的SQL语句看起来如下所示:

UPDATE Product
SET Name = 'Junk' /* @p0 */
WHERE Id = '741bd189-78b5-400c-97bd-9db80159ef79' /* @p1 */
AND Name = 'Stuff' /* @p2 */

这就确保了用户读取数据后直到更新提交时Name的值没有被其他用户更新过(其他用户有可能已经更新过,如果已经更新过了,则上述SQL语句将不会更新任何行),然而,其他用户也可能已经更新了Product对象的其它字段的值了。

另外一个选择是设置optimistic-lock的值为all,这样设置以后,Product对象的自动产生的update语句看起来如下所示:

UPDATE Product
SET Name = 'Junk' /* @p0 */
WHERE Id = 'd3458d6e-fa28-4dcb-9130-9db8015cc5bb' /* @p1 */
AND Name = 'Stuff' /* @p2 */
AND Description = 'Cool' /* @p3 */
AND UnitPrice = 100 /* @p4 */

或许你已经猜到了,这种情况下,我们需要检验所有的属性的值,如果字段非常多的情况那是不太适合的。

当设置optimistic-lock的值为dirty时,dynamic-update的值必须设置为true。动态更新意味着update语句仅仅更新了变化了的属性值,而当dynamic-update设置为false时,update是在应用程序启动的时候就初始化了,它包含了实体的所有属性的值。

NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译的更多相关文章

  1. NHibernate&period;3&period;0&period;Cookbook第一章第五节Setting up a base entity class

    Setting up a base entity class设置一个实体类的基类 在这节中,我将给你展示怎么样去为我们的实体类设置一个通用的基类. 准备工作 完成前面三节的任务 如何去做 1.在Ent ...

  2. 第一百一十六节,JavaScript,DOM操作样式

    JavaScript,DOM操作样式 一.操作样式 CSS作为(X)HTML的辅助,可以增强页面的显示效果.但不是每个浏览器都能支持最新的CSS能力.CSS的能力和DOM级别密切相关,所以我们有必要检 ...

  3. 【PY从0到1】第六节 用户输入while循环

    # 6 第六节 用户输入while循环 # 1> 重要的函数--input() # 我们先讲解一下input():当Python碰到input()后会执行括号内的语句. # 随后等待用户的输入. ...

  4. tensorflow2&period;0学习笔记第一章第四节

    1.4神经网络实现鸢尾花分类 import tensorflow as tf from sklearn import datasets import pandas as pd import numpy ...

  5. 第一章-第六题(帮人抢票,帮人选课这些软件是否合法 你怎么看&quest;)--By梁旭晖

    我觉得这些软件是合法的,符合道德规范的. 计算机当初设计的初衷就是简化甚至替代人类的工作.而软件作为计算机硬件的驱动着,其设计就是体现这些原则. 现在互联网上的订票,选课类型的网站还是有很多的,比如: ...

  6. tensorflow2&period;0学习笔记第一章第五节

    1.5简单神经网络实现过程全览

  7. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  8. Android开发训练之第五章第六节——Transferring Data Using Sync Adapters

    Transferring Data Using Sync Adapters GET STARTED DEPENDENCIES AND PREREQUISITES Android 2.1 (API Le ...

  9. 实验楼学习linux第一章第四节linux目录结构及文件基本操作

    linux目录结构及文件基本操作 常用命令 切换目录 cd 当前目录 . 上一级目录 .. (.和..开头的都是隐藏文件) 查看隐藏文件 ls -a 上一级所在目录 - 当前用户home目录 ~ 获取 ...

随机推荐

  1. macbook air 安装win7双系统

    转自: http://jingyan.baidu.com/article/6d704a13f99f1a28da51ca49.html 1)遇到“No bootable device-insert bo ...

  2. windows Android 开发环境

    步骤: 1)下载jdk,注意这是安装路径,不是目标路径,忘记了怎么看勒,安装路径的lib文件夹下面有个tools.jar 文件,这个也是等下需要的. 2) 在path 中添加 ;%JAVA_HOME% ...

  3. 下拉刷新控件&lpar;1&rpar;PullToRefreshList示例

    有很多控件都可以下拉刷新如,ListView,ExpandableListView,GridView,ScrollView,ViewPager,WebView等, 其中最常见的是ListView.本文 ...

  4. TFT ST7735的Netduino驱动

    好久没写关于netduino的文章了,工作忙是一方面,主要原因还是因为没解决TFT显示的问题,功夫不负有心人,在经过多轮研究后,总算在今天2013年12月15日的晚上9点解决了. 下面先介绍一下我所用 ...

  5. Programming In Scala笔记-第二、三章

    本系列博客以<Programming in Scala 2nd Edition>为主,围绕其中的代码片段进行学习和分析. 本文主要梳理Chapter2和Chapter3中涉及到的主要概念. ...

  6. &period;NET之JSON序列化运用

    1.项目引用NuGet包:搜索:Newtonsoft.Json 2.序列号实例 using System; using System.Collections.Generic; using System ...

  7. bootstrap4的出现&lpar;或这篇文章可以叫做bs4与bs3的区别&rpar;

    前言:在bootstrap4出现之后修改了bootstrap3的不方便之处,让使用框架的前端开发者更加便捷..(bootstrap下文中简称为bs) 一.栅格系统 相对于原来的bs3,bs4具有了范围 ...

  8. &lbrack;PHP&rsqb; 解决人人商城收银台不能上传图片问题

    反正网上一大堆,也不知道哪个版本有修复,反正我的没有修复. 问题报错:ReferenceError: angular is not defined 解决如下: 修改文件:addons/ewei_sho ...

  9. Typecho——简介及安装

    Typecho Typecho是由type和echo两个词合成的,来自于开发团队的头脑风暴.Typecho基于PHP5开发,支持多种数据库,是一款内核强健﹑扩展方便﹑体验友好﹑运行流畅的轻量级开源博客 ...

  10. SQL SERVER 字符合并多行为一列

    [字符合并多行为一列] 思路1:行转列,在与字符拼接(适用每组列数名相同) 思路2:转xml,去掉多余字符(适用所有) 假设兴趣表Hobbys Name Hobby 小张 打篮球 小张 踢足球 Nam ...