Я работаю с интерфейсом Access 2007, связанным с бэкэнд SQL Server 2008 R2, и столкнулся с тем, что, по моему мнению, является странным действием блокировки, вызванным даже простыми поисковыми запросами. Более конкретно:MS Access passthrough select запрос, вызывающий блокировку страницы в SQL Server
У меня есть транзитный запрос простой формы «SELECT * FROM tbl_A». Если я открою этот запрос в доступе (просмотр запроса в стандартном представлении данных), и в таблице будет достаточно много записей (примерно> 100 записей, я не экспериментировал, чтобы найти точную привязку), тогда я получаю блокировку этой таблицы в SQL Server для пока я держу запрос открытым. Если я попытаюсь запустить запрос на обновление или что-то подобное на столе, это приведет к взаимоблокировке. То же самое происходит, если я открываю непрерывную форму, которая имеет этот сквозной запрос, заданный как источник записи. Глядя на представление sys.dm_tran_locks в SQL Server показывает, что это блокировка IS на странице данных ... не знаю, помогает ли это. Как только я нажму кнопку «Последняя запись» в разделе «Доступ», чтобы перейти к концу запроса или формы, блокировка будет удалена, а другие мои процессы снова смогут обновить таблицу.
Насколько я могу видеть, мои свойства формы и/или запроса установлены в их значения по умолчанию (тип набора записей = dynaset, блокировка записи = блокировки). На основе описания динасетов, например, приведенный здесь: https://msdn.microsoft.com/en-us/library/bb188204.aspx Я бы ожидал, что он загрузит только небольшие партии данных, необходимые для заполнения области просмотра, без блокировки сервера в течение длительного периода времени. Как связана статья говорит:
Потому что они работают только несколько строк, в то время, динамические подмножества минимизировать продолжительности, что читать блокировки удерживаются на сервере. Это позволяет другим пользователям изменять данные без необходимости ждать столько, сколько необходимо для блокировки для очистки.
Может ли кто-нибудь объяснить, почему dynaset работает не так, как ожидалось?
Я видел несколько возможных обходных решений, например.
- используя NOLOCK подсказки (как это было предложено здесь MS Access holds locks on table rows indefinitely, но мне кажется, NOLOCK не рекомендуется вообще?)
- с помощью отключенного набора записей ADO как recordsources для моих форм
- тянущих данные с сервера в временные таблицы на стороне клиента и основываясь на тех временных таблицах
- перепроектируйте интерфейс, добавьте ограничители и т. д., чтобы формы никогда не тянули больше, чем 100 записей (было бы много работы и казалось бы небезопасным без гарантии, что оно будет никогда не блокировать с указанным количеством записей)
Все эти предложения либо не работают для меня, либо, похоже, имеют много других недостатков и/или требуют серьезного перезаписи интерфейса ... Каков наилучший способ обойти эту проблему?
У вашей базовой таблицы на SQL Server есть уникальный кластеризованный индекс? Не имея возможности вводить определенные проблемы, хотя и не обязательно это. У вас есть возможность использовать проект Data Access Project? Затем вы можете использовать OLEDB вместо ODBC ... – mroach
Вы пытались изменить привязанную таблицу к режиму моментального снимка? Было бы интересно узнать, изменит ли это поведение. – mroach
Спасибо за комментарии @mroach. Да, таблица имеет уникальный кластеризованный индекс. Моя проблема возникает даже при использовании чистого запроса-транзита (без связанной таблицы), я не уверен, что вы подразумеваете под «привязанной таблицей к режиму моментального снимка». Я попытался изменить форму «тип набора записей» на моментальный снимок, но это ничего не меняет. – Maxbromo