Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
В 1С ситуация = хуже некуда... 03.08.05 12:43 Число просмотров: 2700
Автор: leo <Леонид Юрьев> Статус: Elderman Отредактировано 03.08.05 16:01 Количество правок: 2
|
Решил ответить в форум, может кто-то что-нибудь добавит.
Удалось немного пообщаться с некоторыми (бывшими) разработчиками 1С. Стало ясно, почему с многопользовательским режимом во всех версиях 1С очень плохо. Опишу подробно, чтобы всем было ясно, в чем дело. Сразу оговорюсь, я не программировал для 1С (бог миловал), и не знаком с её внутренностями. Всё что написано ниже – мое видение ситуации на основе информации, полученной от нескольких разных людей. Разобраться было интересно, чтобы выяснить, почему 1С никак не решает эти проблемы.
Изначально ядро 1С разрабатывалось с прицелом на «персональность», про многопользовательские режимы никто даже не думал. Соответственно организация разделения доступа (блокировок) не продумывалась, язык и engine имели предметно-чайниковую (около бухгалтерскую) направленность. Архитектура делалась по принципу – сейчас сделаем как проще, потом разберемся и доделаем.
Первые версии работали под DOS в однопользовательском режиме, с разделением доступа проблем нет. Для организации двух-трех рабочих мест достаточно файл-сервера и простейшего итеративного механизма блокировки. Работает он так: каждый из конкурирующих процессов, «не задумываясь», пытается заблокировать нужные ему таблицы, по очереди, но в любом порядке. Если удается поставить все блокировки, то выполнение продолжается. Если хотя-бы одна из таблиц уже используется другим пользователем, то уже установленные блокировки снимаются, и делается ещё одна итерация по «полному циклу». Если блокировки не удалось «расставить» за N-ое кол-во попыток или за некоторый период времени, то возвращается код ошибки.
Такой подход:
1) Позволяет разработчикам никак не заботиться о порядке блокирования таблиц;
2) Тривиально реализуется в уже написанном «однопользовательском» коде;
3) Неплохо работает в Novell-подобных средах, при небольшом кол-ве пользователей;
4) Почти идеален для небольших фирм, где с 1С работают 1-2 бухгалтера и директор. Как правило, пользователи не замечают проблем с взаимными блокировками;
Разработчики 1С сделали так пошли «дальше». Чтобы при конфликте блокировок пользователи могли знать, почему им не дают работать, реализовали систему «флажков». Процесс блокировки дополнился установкой флажков вида «таблицы X, Y, Z заняты модулем A, который для пользователя B выполняет процедуру C». Это немного увеличило трафик блокировок, конкуренция за таблицу флажков стала критической, но если взять за правило блокировать первой таблицу с флажками, то это «бутылочное горлышко» было удобным местом мониторинга и немного упорядочивало очередность.
Потом стало ещё хуже. Разработчики системы и «программисты»-предметники наплодили кучу рецептов, шаблонов кода и «подходов» к реализации многих «бухгалтерских» подзадач. Во многих этих «кубиках-конструкторах» устанавливаются глобальные флажки-индикаторы, типа «генерировать отчеты А, Б и делать проводки С нельзя, потому, что происходит процесс D». Передергивание нескольких глобальных флажков даже при тривиальных операциях стало нормой. Снежный ком блокировок укатал всех, а SQL-серверы стали «спать» на журнале транзакций…
Поэтому 1С одинаково плохо работает, как на DBF-файлах, так и на SQL-транзакциях. Для избавления от итеративных блокировок нужно получать доступ к таблицам в строго определенном порядке (например отсортировав по названию). Соответственно на уровне языка должно быть заложена конструкция «начать транзакцию с доступом к таблицам A, B, C…». Сделать это не всегда возможно, обращение к «библиотечным» процедурам или методам объектов обычно порождает сложно-контролируемую вложенную активность.
По-хорошему выход только один – компилятор, который анализирует процедурно-объектную модель и строит списки таблиц используемых в каждой транзакцией. Либо двух проходное (на самом деле много проходное) выполнение. На первом проходе выявляются используемые объекты, потом они блокируются, и на втором проходе выполняется код. Проблема в доступе к таблицам по условию, их нужно либо блокировать все сразу, либо реализовывать спекулятивное выполнение и многопроходность (но в конечном итоге это снова приводит к итеративному механизму).
Я делал подобный engine в начале 90-х, поэтому отчасти помню проблему. Решить задачу с блокировками мне тогда так и не дали, ситуация и аргументы схожие – зачем делать то, без чего можно обойтись сейчас...
Перенос БД 1С на SQL (или другие СУБД) ничего не дает без ликвидации итеративного механизма блокировок и избавления от «дребезга» глобальных флажков. Или другими словами переписи огромного кол-ва кода 1С-приложений (ака конфигураций), переучивания людей и т.д. Самое главное – это нужно продать по-новой тем, кто уже обжегся. Делать этого конечно никто не будет, 1С – прежде всего дистрибьюторская фирма, которая продаёт, а не разрабатывает ПО.
Как резюме – решить проблему толком не возможно. Нужно вместо 1С сделать как минимум 2С. В конкретной описанной ситуации (waste-loops while locking) можно попробовать подменить db-engine.dll и пропускать всю активность «через» глобальный семафор. Это даст гарантию, что в waste-loop попадёт не более одного CPU, но и только один будет работать с данными (имеем 1C на DBF в Terminal Server). Но есть большая вероятность (даже очень большая) получить dead-lock. Нужно пробовать...
|
|
|