-
Здравствуйте! Существует программа на D7, работает с БД Access, для связи используется ADO. В БД порядка 100 таблиц и нескольких десятков тысяч записей. БД используется локально. Программа находится в интенсивной эксплуатации и, как всегда, возникают пожелания пользователей - это вернуть, как было, а это - сделать по-новому. В общем, без модификации структуры БД и наполнения системных справочников (информацию в которых не может поменять простой пользователь) не обходиться. До этого все было просто - событие AdoConnection.AfterConnect, по нему прогоняется автомодификция БД до последней версии (присутствует удаление и добавление столбцов, вставка данных с предварительной проверкой - все через отдельную ADOQuery). Потом старт транзакции - пользователь может работать с новой версией.
Сейчас (когда кол-во таких модификаций неуклонно растет, остановиться нельзя), хочу сделать перестраховку, которую не предусмотрели с самого начала (рассчитывали на строго конечное кол-во модификаций). А именно, т.к. баз наплодили дикое кол-во, могу допустить, что в 1 случае из 200-300 система предварительного апгрейда до новой версии БД может дать сбой.
В связи с этим решение - как только срабатывает событие AdoConnection.AfterConnect делать апгрейд БД, но весь код апгрейда начинать и завершать (соответственно) началом и фиксацией (или откатом с выдачей сообщения) транзакции. Только потом в случае успеха пользователь может работать с программой, в случае сбоя – должен сообщить об ошибке. Естественно, весь апгрейд БД ставится в try…except… со всеми необходимыми действиями. “Обрамление” немаленькой (уже примерно 5500 строк) процедуры модификации структуры БД тремя строчками Adoconnection1.BeginTrans; Adoconnection1.CommitTrans; Adoconnection1.RollbackTrans; привело, собственно, к моему вопросу.
Отмечу сразу, что БД и прототип приложения на Delphi, содержащий всего лишь требуемый ADOConnection и событие после подключения (чтобы отвязаться от всего остального) были вынесены мной в отдельный проект. Не помогло. Проблема состоит в следующем – на определенных действиях (повторяется раз от раза), а именно команде добавления столбца в таблицу (ALTER через ADOQuery) получаю сообщение “Таблица такая-то не может быть заблокирована ядром БД, т.к. используется другим пользователем или процессом”. При этом проект, кроме апгрейда, полностью “голый”, без обрамления апгрейда транзакцией – все работает. Единственно, на что можно подумать, “выше” ALTER по коду стоят SELCT и два INSERT’а в эту таблицу. Там, где были объекты ADOQuery, создаваемые в runtime, все уничтожается вовремя (а потом и от них избавился почти), чтобы не было подозрений, что кто-то неуничтоженный продолжает блокировать таблицу. В каком направлении можно двигаться (кроме минимизации кода и всего того, что уже попробовал)?
В процедуре апгрейда присутствуют следующие приемы модификации: alter table test add column test tinyint; Select * from <table_name> where…. (для проверок) alter table drop column test; insert и update…. (вставка и модификация данных) create (drop) table…
Еще есть изменение проверочных условий на столбцы Access с помощью ADOX.Catalog, но нечасто и с описанной выше ошибкой не пересекаются.
Что можно попробовать? С уважением, Николай
-
нет ничего надежнее, чем делать резервную копию базы перед применением глобальных модификаций. С проверкой "правильности" резервной копии. И с восстановлением бд из резервной в случае сбоя.
-
Проблема состоит в следующем – на определенных действиях (повторяется раз от раза), а именно команде добавления столбца в таблицу
Если не слишком секретно, то хотя бы примерно о задаче, в которой любой пользователь "по своему усмотрению" может добавлять какие-то (про количество не спрашиваю) поля в таблицы?
-
> Smile (27.05.10 16:14) [2]
Это же апгрейд. При чем тут "любой пользователь"
-
> [0] Николай2010 (27.05.10 14:39)
Т.е. у вас много пользователей юзают каждый свою копию программы и БД?
-
2 Sergey13
По постановке много пользователей юзают последнюю версию программы (не любую) и свои БД. Причем БД может быть хоть месячной, хоть двухгодичной давности - программа при первом подлючении проапдейтит ее до последней версии. В плане данных апдейтятся внутренние и служебные таблицы, правка данных в которых обычным пользователям запрещена.
-
> [5] Николай2010 (27.05.10 17:48)
Странная постановка задачи. Сети что ли нет? Тогда откуда берутся последние версии программы? Есть сеть - тогда почему бы не юзать одну БД всем вместе? Инначе ИМХО можно до абсурда дойти, когда программа будет по пол дня проверять и осуществлять обновление БД.
-
2 Sergey13 организация очень распределенная по городам, сети нет, глючные локалки в паре офисов не в счет. Пользователи с комплектом программ локально работают. Наша часть работает норм. в общем, причина в alter, http://msdn.microsoft.com/en-us/library/aa141499(office.10).aspx
-
> в общем, причина в alter, http://msdn.microsoft.com/en-us/library/aa141499(office.10).aspx а ссылка про не поддерживаемость транзакциями внешних (прилинкованных) источников. т.е. если например меняется подключенная dbf таблица. alter не виноват...
-
см. [1] а как, собственно, происходит процесс апгрейда? просто, предполагается, что обновляемые бд какой-то предпоследней версии и на них накатывается скрипт с дополнениями от последней версии? если так, то это не верный подход.
-
Надо освоить репликации и поддержание целостности при обновлениях структуры.
|