powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
3 сообщений из 78, страница 4 из 4
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459605
Я, конечно, поздно вступаю в дискуссию... Вначале её я думал, что вопрос простой, и поэтому помалкивал, в середине (когда к обсуждению вопроса подтянулись силы главного калибра) - казалось, что по существу вопроса всё уже сказано (или вот-вот будет сказано), и встревать в обсуждение со своими банальностями как-то не хотелось...

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

Пытаюсь восполнить этот пробел.

Насколько я понял, суть вопроса в том, что автор хочет, чтобы при использовании ADO (Microsoft Jet 4.0 OLE DB Provider) для доступа к MDB и применении client-side курсора при добавлении записи блокировалась только одна запись. Реально в этом случае блокируется страница.
Подчеркну, что вопрос не в том, должна ли в конкретном примере здесь возникать блокировка - безусловно должна, учитывая конкретные обстоятельства, а лишь в том, какая у неё должна быть "гранулярность" - запись или страница.

На основании некоторого опыта, довольно глубокого изучения материалов MSDN и результатов собственных экспериментов я пришёл к выводу, что это, похоже, невозможно из-за того, что конкретный ADO провайдер - Microsoft Jet 4.0 OLE DB Provider - такого не предусматривает (возможно, всего лишь по недосмотру).

Вот почему я пришёл к такому выводу:

Свойства объекта Connection - .Mode и .IsolationLevel, а также параметры метода открытия набора записей Open - CursorType и LockType в Microsoft Jet 4.0 влияют на лишь на то, должна или не должна быть блокировка и какая у неё должна быть продолжительность, но никак не затрагивают её детальность ("гранулярность"). Эта самая "гранулярность" (record locking/page locking) в Microsoft Jet 4.0 управляется следующим образом:

1. Меню в MS Access (у меня сейчас русский Access 2000):
Сервис/Параметры, вкладка "Другие", параметр "Блокировка записей при открытии БД"
2. Специфическое свойство провайдера Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Connection:
cnn.Properties("Jet OLEDB:Database Locking Mode")
Page-level Locking - 0
Row-level Locking - 1

3. Специфическое свойство провайдера Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Recordset:
rst.Properties("Jet OLEDB:Locking Granularity")
Page-level locking - 1
Row-level locking - 2
Значение этого свойства принимается во внимание, лишь когда параметр "Jet OLEDB:Database Locking Mode" установлен как Row-level Locking.

Следует отметить, что свойства 1) и 2) - это по сути, одно и то же свойство, и из них принимается во внимание то, что что будет включено раньше для конкретного сеанса (а последующие настройки будут игнорироваться). То есть, если мы откроем базу через программу MS Access, то в силу вступит настройка из меню, и она будет наследоваться всеми последующими соединениями (в том числе и из других программ). И наоборот.

По умолчанию ADO Connection к БД Access открывается как .CursorLocation = adUseServer, и при этом свойство набора записей "Jet OLEDB:Locking Granularity" можно прочитать и настроить, как хочется. В этом случае в обсуждаемом примере (если все вышеназванные свойства настроены как надо) блокируется только одна добавляемая запись независимо от иных настроек - я проверял.

Засада здесь вот в чём. Как только мы выполняем строку
.CursorLocation = adUseClient,
так из свойств объекта Recordset волшебным образом пропадает само свойство "Jet OLEDB:Locking Granularity"! То есть сlient-side курсоры для Microsoft Jet 4.0 OLE DB Provider вообще не поддерживают управление этой самой "гранулярностью"! Естественно, что с этого момента при добавлении записи блокироваться начинают страницами. Это меня окончательно убедило в том, что "this behaviour is by design", как пишут в MS Knowledge Base.

Кстати, вот ещё что хотелось бы отметить. В этой теме неоднократно встречается код типа:

Код: plaintext
1.
    rst.CursorLocation = adUseClient
    rst.Open sql, cnnAccess, adOpenKeyset, adLockOptimistic


Так вот, различные провайдеры ADO поддерживают не все комбинации параметров, и в определённых случаях создают в таких случаях набор записей не с "заказанными" параметрами, а "ближайшими" по их разумению к ним. В частности, в этом конкретном случае вместо набора записей типа adOpenKeyset будет создан набор записей adOpenStatic. Вообще, в случае .CursorLocation = adUseClient Microsoft Jet 4.0 OLE DB Provider ВСЕГДА создаёт набор записей с adOpenStatic, какое бы значение CursorType вы не указали. Кроме того, в этом случае бесполезно указывать вид блокировки adLockPessimistic - он будет заменён на adLockOptimistic.

Отсюда вывод: желательно проверять, когда создаём recordset или connection, какой НА САМОМ ДЕЛЕ объект мы получили. Каждый ADO-провайдер себя ведёт здесь по своему, и даже один и тот же провайдер в зависимости от обстоятельств может вернуть не тот тип набора записей, на который мы рассчитывали, а другой.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459872
acol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хочу уточнить у корифеев принципиальнцую возможность следующего:

Для двух подключений Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Connection

Код: plaintext
1.
2.
3.
4.
5.
      Подключение А                     Подключение Б
 1     Открывается                        Открывается
 2     Начинает транзакцию             
 3     Вносит данные в таблицу Y
 4                                        Вносит данные в таблицу Y 
 5     Закрывает транзакцию



У меня такой фокус не проходит ни при каких параметрах подключения и рекордсета. Считал, что, при включенной транзакции, даже при Row-level Locking = 1 блокируется вся страница.

ЗЫ: Видала я транзакции без блокировок, но что бы блокировки без транзакций... (с) Алиса в стране Акцесс.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459924
Вы знаете, ещё немного поэкспериментировав и в очередной раз помусолив MSDN (из-за скудости информации там приходится читать ну прям буквально между строк!), я пришёл к неутешительному выводу: похоже (при использовании Microsoft Jet 4.0 OLE DB Provider), что никакая комбинация параметров НЕ ГАРАНТИРУЕТ блокировок на уровне записи, и если Jet считает, что нужно использовать страничную блокировку, то он таки её будет использовать, несмотря на твои указания.
Максимум, что можно сколь-нибудь точно выяснить - это при каких обстоятельствах блокировки на уровне записей НЕ БУДЕТ.

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

Более того, мне даже не удалось воспроизвести результаты моих прежних экспериментов, в которых добавление записи в таблицу не блокировало соседние записи. Все настройки, которые требуются для row-level locking, наличествуют, но что-то в окружении изменилось, и Jet упорно использует page-level locking...
...
Рейтинг: 0 / 0
3 сообщений из 78, страница 4 из 4
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]