现在的位置: 首页 > 综合 > 正文

六、NHibernate查询之并发控制

2013年12月20日 ⁄ 综合 ⁄ 共 2359字 ⁄ 字号 评论关闭

一、什么是并发控制?

当许多人试图同时修改数据库中的数据时,必须实现一个控制系统,使一个人所做的修改不会对他人所做的修改产生负面影响。这称为并发控制。

比如说,用户AB同时更新一个账号,其中用户A只需要将Firstname修改为aaa,其它字段不变;而用户B只需将Lastname修改为bbb,其它字段不变

并发控制理论根据建立并发控制的方法而分为两类:

 

二、悲观并发控制(Pessimistic Concurrency)

一个锁定系统,可以阻止用户以影响其他用户的方式修改数据。如果用户执行的操作导致应用了某个锁,只有这个锁的所有者释放该锁,其他用户才能执行与该锁冲突的操作。这种方法之所以称为悲观并发控制,是因为它主要用于数据争用激烈的环境中,以及发生并发冲突时用锁保护数据的成本低于回滚事务的成本的环境中。

简单的理解通常通过独占锁的方法。获取锁来阻塞对于别的进程正在使用的数据的访问。换句话说,读者和写者之间是会互相阻塞的 ,这可能导致数据同步冲突。

 

三、乐观并发控制(Optimistic Concurrency)

在乐观并发控制中,用户读取数据时不锁定数据。当一个用户更新数据时,系统将进行检查,查看该用户读取数据后其他用户是否又更改了该数据。如果其他用户更新了数据,将产生一个错误。一般情况下,收到错误信息的用户将回滚事务并重新开始。这种方法之所以称为乐观并发控制,是由于它主要在以下环境中使用:数据争用不大且偶尔回滚事务的成本低于读取数据时锁定数据的成本。

 

四、NHibernate支持乐观并发控制

NHibernate提供了一些方法来支持乐观并发控制:在映射文件中定义了<version> 节点和<timestamp>节点。其中<version> 节点用于版本控制,表明表中包含附带版本信息的数据。<timestamp>节点用于时间截跟踪,表明表中包含时间戳数据。

 

五、实例分析

下面用一个例子来实现乐观并发控制,这里使用Version版本控制。

1.修改持久化Customer类:添加Version属性

    //注意,实体类必须为public,否则无法访问

    public class Customer

    {

        //NHibernate的实体类中,所有的公共方法、属性和事件都必须使用virtual修饰

        public virtual int CustomerId { get; set; }

        public virtual string Firstname { get; set; }

        public virtual string Lastname { get; set; }

        //版本控制

        public virtual int Version { get; set; }

    }

 

2.修改映射文件:添加Version映射节点

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model.Entities">

  <class name="Model.Entities.Customer,Model" table="Customer">

    <id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">

      <generator class="native"></generator>

    </id>

    <!--如果要使用version进行版本控制,version节点在映射文件中必须在主键后面-->

    <version name="Version"  column="Version" type="int" unsaved-value="0"></version>

    <property name="Firstname" column="Firstname" type="string" length="50" not-null="false"></property>

    <property name="Lastname" column="Lastname" type="string" length="50" not-null="false"></property>

  </class>

</hibernate-mapping>

 

3.修改数据库,添加Version字段

具体参数:[Version] [int] NOT NULL 默认值为1

4.并发更新测试

在测试之前,先看看数据库中什么数据,预知一下:

编写测试:

        [Test]

        public void UpdateConcurrency()

        {

            Customer c1 = _customerAcc.GetCustomerById(1);

            Customer c2 = _customerAcc.GetCustomerById(1);

            c2.Firstname = "firstName_c2";

            c1.Firstname = "firstName_c1";

            _crudAcc.UpdateCustomer(c1);

            _crudAcc.UpdateCustomer(c2);

        }

 

测试后会发现,NHibernate的并发控制即是当对同一个数据的操作出现并发时,只将最新的操作数据更新至服务器,从而忽略其它的并发操作,这样可以减小服务器的负载。(这是我的理解,不过感觉应该是错的,是知道这个种不重要,数据库是不有自己的并发控制吗?总之很多不明白,现在暂且这样)

 

 

 

抱歉!评论已关闭.