如何防止脏记录更新

时间:2009-04-02 09:52:25

标签: c# ado.net enterprise-library

假设产品类

public class Product
{
    public String Name {get;set;}
    public Decimal Price {get;set;}
    public Int32 QuantityStock {get;set;}
}

现在假设两个客户同时“请求”同一产品,并使用以下值命名为“产品1”

名称=“产品1”

价格= 10

QuantityStock = 100

第一个客户将QuantityStock增加到110

然后第二个客户将QuantityStock减少到90

所以我的产品缺少10个数量库,因为第二个客户更新数量库从原始值“100”而不是第一个客户更新“110”......

原始值= 100

First Client Update 100 => 110

第二次客户端更新100 => 90

我该如何防止这种行为?

注意:我处于具有存储库模式和企业库的3层体系结构中。

3 个答案:

答案 0 :(得分:2)

我在记录上使用了一个时间戳,并在我将记录提交到数据库之前确认记录的时间戳保持不变。如果时间戳已更改,即客户端1已执行其提交,因为客户端2已读取数据,则采取适当的操作。

对于你已经指出的动作,我很想把它变成一个调整而不是绝对,所以它要么是从系统中增加或减去股票。这样你就不会担心争用了。

答案 1 :(得分:0)

我会从这个选项列表中选择第四位:http://davidhayden.com/blog/dave/archive/2005/10/05/2503.aspx

  

检查更新期间时间戳(rowversion)的更改。

答案 2 :(得分:0)

看一下这篇文章:

SQL Server - Optimistic Concurrency Database Updating - Pessimistic Concurrency - High Performance ASP.NET Websites

此处(文章末尾):

Developing Next Generation Smart Clients using .NET 2.0 working with Existing .NET 1.1 SOA-based XML Web Services

示例:

var reader = SqlHelper.ExecuteReader(connectionString,
    "UpdateProduct", product.Name, product.Price, product.StockQuantity);    
if (reader.RecordsAffected > 0)
{
    RefreshEntity(reader, product);
    result = reader.RecordsAffected;
}
else
{
    //must always close the connection
    reader.Close();

    // Concurrency exception
    DBConcurrencyException conflict = 
       new DBConcurrencyException("Concurrency exception");
    conflict.ModifiedRecord = product;

    AssessmentCollection dsrecord;
    // Get record from Datasource
    if (transactionManager != null)
        dsrecord = ProductRepository.Current.GetByName(
        this.transactionManager, product.Name);
    else
        dsrecord = ProductRepository.Current.GetByName(connectionString, 
            product.Name);
    if (dsrecord.Count > 0)
        conflict.DatasourceRecord = dsrecord[0];

    throw conflict;
}