Как предотвратить грязные записи, которые будут обновлены - PullRequest
0 голосов
/ 02 апреля 2009

Принимая класс продукта

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

Теперь предположим, что два клиента, которые «запрашивают» один и тот же продукт одновременно, назвали «Продукт 1» со следующими значениями

Имя = "Продукт 1"

Цена = 10

Количество товара = 100

Первый клиент увеличит количествоStockStock до 110

Тогда второй клиент уменьшит количествоStockStock до 90

.

Таким образом, я получил нехватку 10 QuantityStock для этого продукта, потому что второй клиент обновил количествоStockStock с исходного значения "100" вместо первого обновления клиента "110" ...

Исходное значение = 100

Первое обновление клиента 100 => 110

Второе обновление клиента 100 => 90

Как я могу предотвратить такое поведение?

Примечание. Я работаю в трехуровневой архитектуре с шаблоном репозитория и библиотекой Entreprise.

Ответы [ 3 ]

2 голосов
/ 02 апреля 2009

Я использовал бы метку времени в записи и подтвердил, что метка времени записи осталась нетронутой до того, как я отправил запись в базу данных. Если временная метка изменилась, то есть клиент 1 выполнил свою отправку после того, как клиент 2 прочитал данные, затем примите соответствующие меры.

Для действия, которое вы указали, у меня возникнет соблазн сделать его корректировкой, а не абсолютом, так что это либо добавление, либо вычитание акций из системы. Таким образом, вы не так обеспокоены разногласиями.

0 голосов
/ 02 апреля 2009

Посмотрите на эту статью:

SQL Server - Обновление баз данных с оптимистичным параллелизмом - Пессимистичный параллелизм - Высокопроизводительные веб-сайты ASP.NET

А также здесь (в конце статьи):

Разработка интеллектуальных клиентов следующего поколения с использованием .NET 2.0, работающих с существующими веб-службами XML на основе SOA .NET 1.1

Пример:

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;
}
0 голосов
/ 02 апреля 2009

Я бы выбрал номер четыре из этого списка вариантов: http://davidhayden.com/blog/dave/archive/2005/10/05/2503.aspx

Проверка изменений метки времени (rowversion) во время обновления.

...