Форум: "Базы";
Текущий архив: 2012.04.22;
Скачать: [xml.tar.bz2];
ВнизAccess+Delphi+Ado - про транзакции Найти похожие ветки
← →
Николай2010 (2010-05-27 14:39) [0]Здравствуйте!
Существует программа на 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, но нечасто и с описанной выше ошибкой не пересекаются.
Что можно попробовать?
С уважением, Николай
← →
turbouser © (2010-05-27 15:51) [1]нет ничего надежнее, чем делать резервную копию базы перед применением глобальных модификаций. С проверкой "правильности" резервной копии. И с восстановлением бд из резервной в случае сбоя.
← →
Smile (2010-05-27 16:14) [2]Проблема состоит в следующем – на определенных действиях (повторяется раз от раза), а именно команде добавления столбца в таблицу
Если не слишком секретно, то хотя бы примерно о задаче, в которой любой пользователь "по своему усмотрению" может добавлять какие-то (про количество не спрашиваю) поля в таблицы?
← →
turbouser © (2010-05-27 16:18) [3]
> Smile (27.05.10 16:14) [2]
Это же апгрейд. При чем тут "любой пользователь"
← →
Sergey13 © (2010-05-27 16:28) [4]> [0] Николай2010 (27.05.10 14:39)
Т.е. у вас много пользователей юзают каждый свою копию программы и БД?
← →
Николай2010 (2010-05-27 17:48) [5]2 Sergey13
По постановке много пользователей юзают последнюю версию программы (не любую) и свои БД. Причем БД может быть хоть месячной, хоть двухгодичной давности - программа при первом подлючении проапдейтит ее до последней версии. В плане данных апдейтятся внутренние и служебные таблицы, правка данных в которых обычным пользователям запрещена.
← →
Sergey13 © (2010-05-27 17:57) [6]> [5] Николай2010 (27.05.10 17:48)
Странная постановка задачи. Сети что ли нет? Тогда откуда берутся последние версии программы? Есть сеть - тогда почему бы не юзать одну БД всем вместе?
Инначе ИМХО можно до абсурда дойти, когда программа будет по пол дня проверять и осуществлять обновление БД.
← →
Николай2010 (2010-05-27 21:03) [7]2 Sergey13
организация очень распределенная по городам, сети нет, глючные локалки в паре офисов не в счет. Пользователи с комплектом программ локально работают. Наша часть работает норм.
в общем, причина в alter, http://msdn.microsoft.com/en-us/library/aa141499(office.10).aspx
← →
sniknik © (2010-05-27 22:56) [8]> в общем, причина в alter, http://msdn.microsoft.com/en-us/library/aa141499(office.10).aspx
а ссылка про не поддерживаемость транзакциями внешних (прилинкованных) источников. т.е. если например меняется подключенная dbf таблица.
alter не виноват...
← →
turbouser © (2010-05-27 23:22) [9]см. [1]
а как, собственно, происходит процесс апгрейда? просто, предполагается, что обновляемые бд какой-то предпоследней версии и на них накатывается скрипт с дополнениями от последней версии? если так, то это не верный подход.
← →
Anatoly Podgoretsky © (2010-05-28 07:23) [10]Надо освоить репликации и поддержание целостности при обновлениях структуры.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2012.04.22;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.003 c