Linq, кэширующий значения данных - главная проблема параллелизма?

Вотум недоверия списки несколько оплошностей и/или недостающих битов функциональности в глазах тех, кто полагает, что знают, какие функции и их реализации, являются надлежащими для платформ ORM/Datamapper.

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

За пределами той проблемы и к основе Вашего вопроса - необходимо следить за Sql, который сгенерирован так, можно сделать тонкие настройки, прежде чем проблема производительности войдет в производство. Даже если бы Вы используете procs на бэкенде, я все еще искал бы сценарии, где можно поражать базу данных слишком много раз и затем переделывать отображения или выбирающие сценарии соответственно.

6
задан Shaul says I Support Monica 30 September 2009 в 16:04
поделиться

4 ответа

Это не та проблема, с которой я сталкивался раньше (поскольку я не склонен держать DataContexts открытыми в течение длительного времени), но похоже, что кто-то еще :

http://www.rocksthoughts.com/blog/archive/2008/01/14/linq-to-sql-caching-gotcha.aspx

5
ответ дан 8 December 2019 в 18:38
поделиться

LinqToSql has a wide variety of tools to deal with concurrency problems.

The first step, however, is to admit there is a concurrency problem to be solved!

First, DataContext's intended object lifecycle is supposed to match a UnitOfWork. If you're holding on to one for extended periods, you're going to have to work that much harder because the class isn't designed to be used that way.

Second, DataContext tracks two copies of each object. One is the original state and one is the changed/changable state. If you ask for the MyClass with Id = 1, it will give you back the same instance it gave you last time, which is the changed/changable version... not the original. It must do this to prevent concurrency problems with in memory instances... LinqToSql does not allow one DataContext to be aware of two changable versions of MyClass(Id = 1).

Third, DataContext has no idea whether your in-memory change comes before or after the database change, and so cannot referee the concurrency conflict without some guidance. All it sees is:

  • I read MyClass(Id = 1) from the database.
  • Programmer modified MyClass(Id = 1).
  • I sent MyClass(Id = 1) back to the database (look at this sql to see optimistic concurrency in the where clause)
    • Обновление будет успешным, если версия базы данных соответствует исходной (оптимистичный параллелизм).
    • Обновление завершится ошибкой с исключением параллелизма, если версия базы данных не соответствует исходной.

Хорошо, теперь, когда проблема указана , вот несколько способов справиться с этим.

Вы можете выбросить DataContext и начать заново. Для некоторых это немного тяжеловесно, но, по крайней мере, его легко реализовать.

Вы можете попросить обновить исходный экземпляр или измененный / изменяемый экземпляр значением базы данных, вызвав DataContext.Refresh (RefreshMode , target) ( справочные документы со множеством хороших ссылок на параллелизм в разделе «Примечания» ). Это внесет изменения на стороне клиента и позволит вашему коду определить, каким должен быть окончательный результат.

Вы можете отключить проверку параллелизма в dbml ( ColumnAttribute.UpdateCheck ). Это отключает оптимистичный параллелизм, и ваш код будет топтать чьи-либо изменения. Тоже тяжеловесный и простой в использовании.

5
ответ дан 8 December 2019 в 18:38
поделиться

Установите для свойства ObjectTrackingEnabled DataContext значение false.

Когда ObjectTrackingEnabled имеет значение true, DataContext ведет себя как Единица работы . Он будет держать любой объект загруженным в памяти, чтобы можно было отслеживать изменения в нем. DataContext должен запомнить объект в том виде, в котором вы его изначально загрузили, чтобы знать, были ли внесены какие-либо изменения.

Если вы работаете в сценарии только для чтения, вам следует отключить отслеживание объекта. Это может быть приличным улучшением производительности.

Если вы не работаете в сценарии только для чтения, я не уверен, почему вы хотите, чтобы это работало именно так. Если вы внесли правки, зачем вам извлекать измененное состояние из базы данных?

2
ответ дан 8 December 2019 в 18:38
поделиться

LINQ to SQL использует шаблон проектирования карты идентификации, что означает, что он всегда будет возвращать один и тот же экземпляр объекта для данного первичного ключа (если вы не отключите отслеживание объекта).

Решение состоит в том, чтобы просто использовать второй контекст данных, если вы не хотите, чтобы он мешал работе первого экземпляра, или обновить первый экземпляр, если вы это сделаете.

1
ответ дан 8 December 2019 в 18:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: