Тайм-ауты доступа 2000 на связанной записи - PullRequest
0 голосов
/ 08 ноября 2011

Взрыв из прошлого ... У меня была задача управлять устаревшим ADP Access 2000, используемым для управления данными, находящимися на сервере SQL 2005. На одной из форм данных каждый раз, когда я пытаюсь внести изменение в поле и сохранить его обратно в базе данных, оно истекает примерно через минуту. Увеличение лимита времени ожидания только задерживает отображение сообщения об ошибке времени ожидания. Я прошел все обычные способы устранения неполадок, чтобы обеспечить совместимость (см., Например, этот вопрос ).

Это настройка: форма привязана к набору записей (который считывается из базы данных как запрос SELECT * FROM table_name. Размер результирующего набора варьируется в зависимости от фильтров, установленных в форме, но результат обычно составляет около 200 записей (не много данных ...). Некоторые поля формы запускают автоматическое сохранение в связанном обработчике событий, который выглядит примерно так:

Private Sub EndDate_Exit(Cancel As Integer)
     some checking goes here...
     ...
     DoCmd.RunCommand acCmdSaveRecord
End Sub

При выполнении кода DoCmd.RunCommand acCmdSaveRecord ADP зависает до тех пор, пока не получит ошибку тайм-аута. Углубившись в это немного глубже, я посмотрел на Activity Monitor на SQL Server. acCmdSaveRecord запускает оператор UPDATE обратно на сервер, чтобы сохранить измененные данные. Сам оператор автоматически создается MS Access на основе первичного ключа базовой таблицы, который, по-видимому, определен правильно. Тем не менее обновление блокируется запущенным оператором SELECT, что соответствует запросу SELECT * FROM table_name, упомянутому выше.

Это приводит к тупику: изменение пользователя вызывает UPDATE, который блокируется запущенным SELECT (который, как представляется, возник из редактируемой формы). Как я могу обойти это?

Вещи, которые мы пробовали:

  1. Мы удалили оператор DoCmd.RunCommand acCmdSaveRecord и заменили его кодом Me.Dirty = False, что приводит к тому же поведению, как описано выше.
  2. Удалено заполнение acCmdSaveRecord и использование встроенного меню доступа для сохранения изменений. Эта функциональность эквивалентна # 1 и ведет к точно такому же поведению.
  3. Замените вызов acCmdSaveRecord хранимой процедурой, которая сохраняет изменения в определенном поле. Прекрасно работает, за исключением того, что сохранение всей записи из GUI (кнопка сохранения, которая вызывает acCmdSaveRecord) приводит к той же тупиковой ситуации.
  4. Уменьшен размер результирующего набора, связанного с формой, до нескольких записей. Как ни странно, все еще демонстрирует EXACT такое же поведение.

1 Ответ

1 голос
/ 08 ноября 2011

Звучит так, как будто вы установили уровень изоляции транзакции на SERIALIZABLE для своего соединения в какой-то момент.См. УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ ТРАНЗАКЦИЙ (Transact-SQL) для получения более подробной информации.Вот соответствующая выдержка (выделение выделено):

SERIALIZABLE

Указывает следующее:

  • Операторы не могут читать данные, которые были измененыно еще не зафиксированы другими транзакциями.

  • Никакие другие транзакции не могут изменять данные, считанные текущей транзакцией, до тех пор, пока текущая транзакция не завершится.

  • Другие транзакции не могут вставлять новые строки со значениями ключей, которые попадают в диапазон ключей, считываемых любыми инструкциями в текущей транзакции, пока текущая транзакция не завершится.

Блокировки диапазона помещаются в диапазон значений ключа, которые соответствуют условиям поиска каждого оператора, выполненного в транзакции.Это блокирует другие транзакции от обновления или вставки любых строк, которые соответствуют требованиям любого из операторов, выполняемых текущей транзакцией.Это означает, что если какой-либо из операторов в транзакции выполняется во второй раз, они будут читать тот же набор строк.Блокировки диапазона удерживаются до завершения транзакции. Это наиболее ограничительный из уровней изоляции, поскольку он блокирует все диапазоны ключей и удерживает блокировки до завершения транзакции. Поскольку параллелизм ниже, используйте эту опцию только при необходимости.Этот параметр имеет тот же эффект, что и установка HOLDLOCK для всех таблиц во всех инструкциях SELECT в транзакции.

...