ChangeConflictException в Linq для Sql не одновременных обновлений - PullRequest
0 голосов
/ 19 июня 2009

Я использую LINQ to SQL, и у меня возникла небольшая проблема, увеличивающая кросс-соединение счетчика просмотров.

Небольшой фрагмент кода, который я использую:

t = this.AppManager.ForumManager.GetThread(id);
t.Views = t.Views + 1;
this.AppManager.DB.SubmitChanges();

Сейчас в моих тестах я запускаю это несколько раз, не одновременно. Всего существует 4 копии объекта, выполняющего этот тест.

То есть, нет проблемы с блокировкой или что-то в этом роде, но есть 4 контекста данных.

Теперь я ожидаю, что это будет работать так: извлекать строку, изменять поле, обновлять строку. Однако это вызывает исключение ChangeConflictException.

Почему изменение будет конфликтовать, если ни одна из его копий не запущена одновременно?

Есть ли способ игнорировать конфликты изменений в определенной таблице?

РЕДАКТИРОВАТЬ: Нашел ответ:

Вы можете установить «UpdateCheck = Никогда» во всех столбцах таблицы, чтобы создать стиль обновления «последний при выигрыше». Это то, что приложение использовало до того, как я перенес его в LINQ, поэтому я буду использовать его сейчас.

EDIT2: Хотя мое исправление, приведенное выше, действительно предотвращало создание исключения, оно не решало основную проблему:

Поскольку у меня более одного контекста данных, в итоге получается более одной кэшированной копии каждого объекта. Должен ли я воссоздавать свой контекст данных при каждой загрузке страницы?

Я бы скорее поручил контексту данных забыть все. Это возможно?

1 Ответ

2 голосов
/ 20 июня 2009

Я считаю, что DataContext имеет относительно легкий вес и недолговечный. IMO, вы не должны кэшировать данные, загруженные с DataContext дольше, чем необходимо. Когда он недолговечный, он остается относительно небольшим, потому что (насколько я понимаю) использование памяти DataContext в первую очередь связано с отслеживанием изменений, которые вы вносите в управляемые им объекты (извлекаемые им).

В приложении, над которым я работаю, мы создаем контекст, отображаем данные в пользовательском интерфейсе, ждем пользовательских обновлений и затем обновляем данные. Однако это необходимо главным образом потому, что мы хотим, чтобы обновление основывалось на том, на что смотрит пользователь (в противном случае мы можем получить данные и обновить все сразу, когда пользователь нажмет на обновление). Если ваши обновления относительно автономны, я думаю, было бы разумно извлечь строку непосредственно перед ее обновлением.

Вы также можете использовать System.Data.Linq.DataContext.Refresh () для повторной синхронизации уже полученных данных с данными в базе данных, чтобы помочь с этой проблемой.

Отвечая на ваш последний комментарий о том, чтобы заставить контекст забыть все, я не думаю, что есть способ сделать это, но я подозреваю, что это потому, что все, что есть в контексте, это отслеживаемые изменения (и соединение), и это также хорошо, что вы создаете новый контекст (не забудьте избавиться от старого), потому что на самом деле вы хотите выбросить все, что является контекстом.

...