Это старый вопрос, но никто так и не ответил на него. Вот вопросы:
- Как обрабатываются параллельные чтения в MDB?
- Как обрабатываются параллельные обновления / удаления в MDB?
- Существует ли концепция блокировок и как ее использовать в приложении .NET?
- Является ли размещение файла MDB на сетевом ресурсе хорошей или ужасной идеей?
На первые два вопроса можно ответить одним объяснением. Одно ключевое предостережение: ответы, которые я даю здесь, относятся к Jet MDB (и их вариантам) и не полностью применимы к новому формату файлов, введенному начиная с A2007, то есть к формату ACCDB. Я не полностью изучил последствия удаления Jet ULS из ACE, и некоторые из комментариев ниже могут предполагать, что Jet ULS находится под капотом. Однако для многих вещей вы можете заменить "LACCDB file" на "LDB file", и результаты будут такими же.
1-2) Одновременное чтение / обновление / удаление
Ядро базы данных Jet часто называют базой данных «файлового сервера», поскольку на сервере нет демона на стороне сервера, управляющего вводом / выводом с помощью файлов данных. Это означает, что все клиенты, использующие Jet MDB, читают файл напрямую.
Это, конечно, рецепт катастрофы, если нет встроенного механизма для обработки одновременного доступа к файлу.
Jet использует файл блокировки записи, где, если ваш MDB - «MyFile.MDB», файл блокировки записи будет находиться в той же папке и называется «MyFile.LDB». Файл LDB записывает, что пользователи Jet ULS имеют открытый файл MDB, с какой рабочей станции подключен этот пользователь, и всю информацию, необходимую для согласования проблем параллелизма.
Теперь, для тех, кто режет зубы на ядро клиент-серверной базы данных, это может показаться примитивным и опасным, но в то время, когда ядро базы данных Jet разрабатывалось, его целью было использовать его в качестве движка базы данных для настольных компьютеров для небольших рабочих групп. и он конкурировал с другими настольными механизмами БД, такими как xBase и Paradox, которые использовали аналогичные блокирующие файлы для управления одновременным использованием файлов данных от нескольких клиентов.
В файле базы данных Jet блокировки применяются либо к страницам данных (которые в Jet 4 были увеличены до 4 КБ, тогда как в Jet 3.x и ранее они были 2 КБ), либо на уровне записи, если таблица данных была изначально создан для использования блокировки на уровне записей. В первые дни Jet 4 многие находили блокировку на уровне записи довольно медленной, особенно при использовании пессимистической блокировки, поэтому многие разработчики Access никогда не использовали ничего, кроме блокировки на уровне страниц (@David Fenton поднимает руку!).
Фактически, при использовании оптимистической блокировки вы избегаете большинства проблем параллелизма, которые могут возникнуть при пессимистической блокировке.
Некоторые предостережения:
от DAO, блокировка на уровне записи недоступна, и вы только когда-либо получаете блокировку на уровне страницы.
из DAO, есть ряд опций для управления оптимистической / пессимистической блокировкой, в частности аргумент LockEdits метода OpenRecordset, но он также взаимодействует с некоторыми настройками, указанными в аргументе параметров OpenRecordset Options (например, Опция dbReadOnly не может использоваться с LockEdits). В дополнение к блокировке, есть также варианты для согласованных / противоречивых обновлений, и все это может взаимодействовать с транзакциями (например, изменения в несвязанной транзакции не будут видны другим пользователям и, следовательно, не будут конфликтовать с ними, но это может устанавливать блокировки только для чтения на соответствующие таблицы).
Из ADO / OLEDB эти структуры управления параллелизмом Jet будут отображаться на соответствующие функции и аргументы, найденные в ADO / OLEDB. Поскольку я использую Jet только из Access, я взаимодействую с ним только через DAO, поэтому я не могу посоветовать, как вы управляете ими с помощью ADO / OLEDB, но дело в том, что ядро базы данных Jet обеспечивает контроль блокировки вашей записи при доступе к ней. программно (в отличие от интерфейса доступа) - это просто сложнее.
3) Замки и .NET
Я не могу дать здесь никакого совета, кроме того, что вы, скорее всего, будете использовать OLEDB в качестве интерфейса данных, но дело в том, что функции блокировки / управления есть в самом движке db, так что, вероятно, есть способ контролировать это через OLEDB. Впрочем, это может быть не очень красиво, так как мне кажется, что OLEDB спроектирован на основе клиент-серверных архитектур, и файловая блокировка Jet может не отображаться на этом элегантным способом.
4) MDB на сетевом ресурсе
Jet очень чувствителен к малейшим сбоям в любом сетевом соединении. Из-за этого сети с низкой пропускной способностью могут увеличить уязвимость баз данных Jet, открытых через медленное соединение.
Это связано с тем, что основные фрагменты файла базы данных должны быть переданы по проводам в оперативную память локального компьютера для обработки. Теперь многие люди ошибочно утверждают, что весь файл MDB протягивается по проводам или что целые таблицы протягиваются по проводам. Это неправда. Вместо этого Jet сначала запрашивает индексы (и запрашивает не больше, чем необходимо для выполнения запроса), а затем на основании этого результата точно определяет, какие страницы данных необходимы, а затем извлекает только эти страницы. Это удивительно эффективно и быстро.
Кроме того, Jet выполняет очень интеллектуальное кэширование, которое может означать, что первый запрос данных может занять некоторое время, но последующие запросы на те же данные происходят почти мгновенно из-за кэширования.
Теперь, если вы недостаточно хорошо проиндексировали свои таблицы, вы можете закончить тем, что потянете всю таблицу и выполните полное сканирование таблицы. Аналогично, если вы основываете критерии на клиентских функциях, которые не являются частью диалекта SQL Jet, вы можете в конечном итоге получить полную таблицу (сортировка, скажем, по Replace (MyField, "A", "Z") может вызвать полное сканирование таблицы). Но такого рода вещи будут неэффективными и с архитектурой клиент / сервер, поэтому достаточно просто спроектировать схему, чтобы правильно индексировать объекты и быть осторожными с использованием UDF или не-совместимых функций. В общем, те же самые вещи, которые эффективны с клиентом / сервером, будут эффективны и с Jet (главное отличие в том, что с Jet вы будете лучше иметь постоянное соединение, чтобы избежать накладных расходов при воссоздании файла LDB, что является значительным).
Другая вещь, которую следует избегать, - это попытаться использовать данные Jet через соединение WiFi. Мы все знаем, насколько ненадежен WiFi, и он просто пытается решить проблему с данными Jet через соединение WiFi.
Суть:
Если вы используете MDB в качестве хранилища данных для обслуживания данных с веб-сервера, вы должны поместить данные как можно ближе к оперативной памяти веб-сервера. Это означает, что, по возможности, на томе диска, который подключен к физическому веб-серверу. Там, где это невозможно, вам нужно быстрое и надежное подключение к локальной сети. Локальные сети GB в центрах обработки данных довольно распространены в наши дни, и мне было бы очень удобно работать с данными Jet через такое соединение.
Для совместного использования, например, нескольких клиентских рабочих станций, на которых запущено настольное приложение VB.NET, совместно использующих один MDB-накопитель Jet в качестве хранилища данных, достаточно безопасно хранить файл данных на надежном файловом сервере. Там, где это возможно, рекомендуется размещать файлы Jet MDB на компьютерах, которые не предназначены для нескольких целей (например, контроллер домена, на котором работает Exchange, SQL Server и который выступает в качестве файлового сервера и сервера печати, может оказаться не лучшим местом) , Такие приложения, как Exchange, могут сильно мешать работе файлового сервера, и я, как правило, рекомендую никогда не размещать файлы MDB на многозадачном сервере в качестве сервера Exchange, если только его объем не слишком мал.
Другие соображения:
никогда не пытайтесь распространять MDB в реплицированной файловой системе, если только все пользователи не используют одну и ту же реплику. То есть, если у вас есть два сервера, реплицирующие файлы между ними, даже не думайте о редактировании файла MDB с обоих серверов. Это почти сразу повредит файл.
Я бы не рекомендовал хранить какие-либо MDB-файлы на чем-либо, кроме собственной файловой системы Windows, обслуживаемой через собственные сети Microsoft SMB. Это означает, что нет Novell, нет Linux, нет SAMBA. Ключевая причина этого заключается в том, что, очевидно, существуют низкоуровневые хуки от Jet для некоторых низкоуровневых блокировок в файловой системе Windows, которые не реплицируются на 100% на другие файловые системы. Теперь я очень консервативен в этом вопросе, и многие компетентные разработчики Access сообщили о превосходных результатах с правильно настроенными файловыми серверами Novell (часто необходимо внести некоторые коррективы в блокировку записи, хотя в наши дни это может быть менее актуально - я не понимаю даже не знаю, существует ли Novell больше!), и невероятная производительность на файловых серверах на базе Linux, работающих под управлением SAMBA. Я осторожен в этом и рекомендую любой клиент против него (в том числе различные устройства SAN, поскольку не многие из них основаны на Windows).
Я бы никогда не запустил их в какой-либо виртуализированной файловой системе по тем же причинам. Однако у меня есть клиент, который уже несколько лет запускает свое однопользовательское приложение Access под Parallels на Mac Air без единой проблемы. Но он однопользовательский, поэтому проблемы с блокировками будут относительно незначительными.
Я не знаю, отвечает ли это на ваши вопросы или нет. Все это основано на моем 13-летнем регулярном использовании Jet в качестве разработчика Access и изучении единственной опубликованной книги по Jet, Руководства для программистов Jet Database Engine (только для Jet 3.5). Я не предоставил никаких реальных ссылок, но если кому-то понадобятся какие-то подробности по поводу того, что я сказал, я проведу исследование, если смогу.