2016-04-13 4 views
1

Я изучаю прерывистое появление Devart.Data.Linq.ChangeConflictException: Row not found or changed.* Не * получение ChangeConflictException с использованием Devart

Я читал статью Devart по адресу concurrency conflicts, и точно так же, как отправная точка, я пытаюсь воспроизвести конфликт параллелизма. Использование включенных классов LINQ на основе MS это легко сделать (использование структуры кода ниже делает это успешно). Однако даже после их примера в статье я не могу создать исключение. Я попытался

  • Использование одновременно ADO paramaterised запроса точно так, как показано в их статье
  • Использование упрощенного запроса ADO, показанный ниже (не беспокоюсь о нападениях инъекций во время этого теста)
  • Использование LinqConnect с новым контекстом (также предлагается в их статье).
  • Приостановка выполнения отладчиком и вручную обновление таблицы с использованием MySQL Workbench.

Это тестовый код, я использую:

public static void MySqlTest() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 

     MySqlAdoChange(db.Connection); 
     //MySqlLinqConnectChange(); 

     customer.Address1 = "Original change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

public static void MySqlAdoChange(DbConnection connection) 
{ 
    connection.Open(); 
    var command = connection.CreateCommand(); 
    command.CommandText = "UPDATE customers SET Address1 = 'Conflicting change" + DateTime.UtcNow.Ticks + "' WHERE Username = 'ian2'"; 
    command.ExecuteNonQuery(); 
} 

public static void MySqlLinqConnectChange() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 
     customer.Address1 = "Conflicting change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

Что вдвойне странно, что значение сохраняется в базе данных чередуется между ними! Мне нужно было добавить отметки DateTime до конца, чтобы обеспечить уникальность, иначе она оптимизировала мое обновление и только обновление, чтобы стать значением, которое в настоящее время не активно.

Может ли кто-нибудь объяснить это поведение? Почему я не могу создать исключение ChangeConflictException?

ответ

1

Прежде всего заметим, что в вашем примере кода, вы обновляете Phone поле в MySqlTest функции, но Address1 поле в MySqlAdoChange функции, так что не может быть какого-либо конфликта.

Однако, скорее всего, даже если вы исправите это, у вас не будет конфликта обновления. Если вы посмотрите на свой исходный код Customer, то в Phone вы, скорее всего, увидите, что он украшен атрибутом Column с UpdateCheck = UpdateCheck.Never (который по умолчанию: см. Здесь https://www.devart.com/linqconnect/docs/MemberMapping.html). Поэтому по умолчанию LinqConnect не будет проверять наличие конфликтов обновлений для ваших полей, если вы не укажете, какие поля нужно проверить, украсив их UpdateCheck = UpdateCheck.Always или UpdateCheck.WhenChanged. Конечно, вы не должны изменять исходный код напрямую, а вместо этого изменять это свойство в дизайнере моделей.

+0

Вы правы, конечно, по телефону или адресу. Первоначально я тестировал поле «Телефон» (которое на самом деле является текстовым полем, но явно не так), затем я решил использовать «Адрес» для «упрощения» вещей и не обновлял вопрос SO правильно. Я рассмотрю атрибут, который вы предлагаете, спасибо за информацию. У меня есть еще один вопрос о щедрости [здесь] (http://stackoverflow.com/questions/36586779/devart-changeconflictexception-but-values-still-written-to-database?lq=1), который вам может быть интересен, этот является лишь подмножеством большей задачи. – Ian

+0

Вы дважды были на месте, мои переменные были _all_ (запрет идентификационных номеров), украшенных атрибутом «UpdateCheck = UpdateCheck.Never». И удаление этого генерирует исключение, как ожидалось. Большое спасибо, что решает половину моей проблемы. Но теперь это еще больше озадачивает мою другую проблему ChangeConflictException. – Ian