суббота, 22 декабря 2012 г.

Какую профессию выбрать? Причины для выбора в пользу Специалиста 1С.




Востребованность на рынке it программистов 1С объясняется просто. Бухгалтерская программа 1С это самая распространенная программа на рынке СНГ. Она часто используется торговыми и производственными компаниями, представителями среднего бизнеса. Для постоянного поддержания финансовой деятельности организации необходим квалифицированный специалист, способный работать в этой программе.

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

Средняя зарплата 1С Программиста по Москве по вакансия в Яндекс 76 000 руб. В чем причина?  - причина в спросе.
(данные на конец 2012 года)


1с программист

~ 76 000 руб.
статистика зарплат в Москве


1000 Вакансий это много даже для Москвы. Я не думаю, что там будет столько свободных программистов.


Сколько организаций в вашем городе? А сколько организаций может обслуживать в месяц 1с Специалист? Я отвечу от 4 до 30. Я сомневаюсь что больше. Чем выше квалификация специалиста тем уже становится рынок которому он предоставляет услуги. Недавно видел статистику по миллионным городам из которой видно, что основная часть программистов находится в двух городах Москва и Санкт-Петербург. 

Какой сделать вывод?! УЧИТЕ 1С и  при усердии с вашей стороны при наличии способностей. У вас будет много интересной работы. 

Удачи в начинаниях!



Что должен знать 1С Программист, вернее сказать что может знать 1С Программист!


Как освоить 1С Предприятие самостоятельно?


Обучение программированию в 1С с нуля.






Хранение удаленных документов. Удаление не на всегда.


УДАЛЕНИЕ ОБЪЕКТА
Для того, чтобы после удаления объекта из конфигурации его можно было восстановить нужно в режиме “КОНФИГУРАТОР” проделать следующие действия.
Ниже приведен пример для управляемых форм в конфигурации Управление торговлей 11. Но этот алгоритм можно применить к любой конфигурации.

Создадим новую подписку на событие «ВыгрузкаУдаляемогоОбъекта» указав в источниках объекты которые мы будем сохранять. Пусть для примера это будут документы и справочники ну и укажем когда будет она будет срабатывать «ПередУдалением»

Для определения обработчика подписки создадим серверный общий модуль «МодульОбработчикаСобытияУдаленияОбъекта»

Укажем наш модуль в подписке в пункте "Обработчик"
Теперь в модуле «МодульОбработчикаСобытияУдаленияОбъекта» пропишем процедуру.

Удаляем документы в УТ 11.
Сначала пометим документ на удаление 
Удаляем их непосредственно

Это наши удаленные объекты один файл на объект.

Так выглядит содержание нашего файла.

ВОСТАНОВЛЕНИЕ ОБЪЕКТОВ
Обработка позволяет восстановить удаленные объекты из конфигурации.
По кнопке “Восстановить объекты”
image
В настройках есть возможность указать каталог в которых хранятся XML файлы удаленных объектов. А также если установить галку “Хранить восстановленные объекты” то поле восстановления объекта файл с его описание будет перемещен в папку “Каталог объектов восстановленных”
image
Ниже предлагаю возможность скачать эту обработку, обработка будет доступна для скачивания до 31.12.2012 г.

Скачать 

После этой даты ее можно будет скачать по адресу.
http://infostart.ru/public/167289/

Или для подписчиков этого блога, отправлю по почте.













среда, 12 декабря 2012 г.

Что должен знать 1С Программист, вернее сказать что может знать 1С Программист!




Администрирование
  • Управление инфраструктурой 1С (есть конфа для ИТ). Ведение списка баз и т.п.
  • Администрирование ОС (в необходимом объеме).
  • Установка, настройка программы 1С (win, unix). Особенности: 1С 7.7 на Win71С Предприятие на ru-board (требуется регистрация). Интернет-сервис для централизованной установки 1С 8.
  • Регистрация общих списков баз? 1,
  • Ключи :) Нюанс настройкиМаркировки! , ещеБлог про администрирование 1С от сисадмина.
  • Администрирование сервера приложений. Настройка кластера.
  • Администрирование SQL сервера, а также других СУБД  (Postgre, IBM DB2, Oracle)
  • Обновление рабочих баз (стандартная инструкция, динамическое обновление, выгон, обновление РИБ, автоматизация обновлений).
  • Организация веб доступа к базе, к веб-хранилищу (статья2 на IIS 7.5, на linux 64bit, …).
  • Автоматическое архивирование (файловой базы, SQL). Backup.
  • Регламентное обслуживание (общая концепция)
  • Перепроведение баз,
  • чистка,
  • Тестирование и исправление (ТиС). Анализ сообщений.
  • Обмены РИБ, в т.ч. автоматизация.
  • регламентированной отчетности
  • Настройка и администрирование SQL сервера. Архивирование/ВосстановлениеОсобенности эксплуатации с 1С.
  • Восстановление поврежденной базы, удаленных файлов и баз (в .т.ч. индексов). Восстановление SQL базы.
  • Безопасность (физический доступ к данным 1с). Шифрование трафика (статья). 6 способов залезть в 1С.
  • Стартеры 1С. По файлам .md и .1cd.
  • Ключи запуска. Пакетный запуск 1С.
  • Управление списком пользователей. Генерация паролей.
  • Завершение работы пользовтелей. Клиент-серверный вариант – консоль. Файловый: 12, …
  • Печать из 1С. В pdf (win&linux, ). Внезапно: чтение из pdf :)
  • Хитрости работы.
Поддержка пользователей
  • Формирование инструкций (инструменты, технические средства)
  • Написание инструкций. Разукрашка кода (и для управляемого приложения).
  • Файлы для скачивания. Дистрибутивы. Шрифт для штрихкода и т.п.
  • Баги (платформы, типовых конфигураций, ОС, сеть)
  • Оптимизация производительности 1С Предприяти (все к Гилеву! другие статьи). От чего зависит скорость?
  • Удаленный доступ (TeamViewer)
  • Регламентированная отчетность
  • Письма в 1С (работа со службой поддержки 1С), банков и других программ.
  • Обновление конфигураций. Сайт для скачивания обновлений – users.v8.1c.ru. Для тех, кто потерял ИТС – ru-board.
  • ИТС. Что, где, почём. Сайт ИТС – its.1c.ru.
  • Список программ (dropboxgroove, …) и другие, которые используются в работе.
  • Управление (в т.ч. уменьшение) размера базы. Как узнать размер?
  • Мониторинг работы пользователей, 1, 2, 3, …
Работа с данными
  • Поиск и исправление ошибок в данных
  • Переносы данных. Обмены. Универсальный обмен XML (с анализом измененных). Сравнение баз (1, 2, 3, )
  • Перенумераторы
  • Список типовых инструментов
  • Поиск и устранение дублей
  • Свертка базы (123 за 4 т.р., …)
  • Подготовка базы (удаление лишних данных, …)
  • Обработки заполнения реквизитов
  • Обработки создания документов
  • Проверки! Здесь начинается другая галактика. “Сто тысяч проверок+1″, проверка ИНН, … 1, 2, 3, …
  • Сервисные функции (Проверка орфографии, …)
  • “Пузомерки”. Статистика базы (1, ).
Программирование на встроенном языке 1С (разработка, написание кода)
  • Освоение азов. С чего начать? Для тех, кто только начинает эту профессию. FAQ. Курсы.
  • Описание встроенного языка. Ссылка.
  • Инструменты разработчика.
  • Кодирование
    • … по методам и общим объектам (это фактически справочная информация)
    • … по подсистемам типовых конфигураций
    • … по объектам (в т.ч. регистры накопления, проводки, расчет)
    • … по компонентам оперативный учет, бухучет, периодические расчеты
    • … по разделам учета (ценообразование, прайсы… закрытие месяца и т.п… отпуска…)
  • Методика разработки от фирмы 1С. (есть пожелания от независимых разработчиков).
  • Вопросы производительности 1С Предприятия.
  • Права (мега огромная тема!)
  • Отладка, Тестирование.
  • Метаданные – список.
  • Модули, Алгоритмы (склонение ФИО, …)
  • Управление временем разработки,
  • Постановка ТЗ! Гост по ТЗ. жизнь без ТЗ :)
  • Язык запросов 1С 8 (123!, …)! Консоль запросов (версии от разработчиков …), Консоль отчетов.
  • СКД (содержание курса, )
  • Веб-сервисы
  • Управляемые формы
  • РИБ
  • Правила обмена между конфами. Между типовыми. Между остальными.
  • Конвертация данных (КД). А это вообще для гурманов: доработка КонвертацииДанных. Потребителей этой доработки, считанные единицы. Предлагаю сделать перекличку :)
  • OLE доступ
  • Доступ к 1С через COM-соединение. Примеры работы (1, …).
  • Печатные формы. Пакетная печать. “Печать этикеток” :) (пример). Цикл статей.
  • Демонстрация возможностей платформы (примеры, трюки, игры и т.п.)
  • Эл. почта
  • Работа с FTP
  • Универсальные подсистемы (разработка от фирмы 1с)
  • Инструменты разработчка (ссылки на Отладку, Консоль запросов)
  • Отчеты
  • Расшифровка отчетов
  • Браузер 1С. Поле HTML документа. События (1, 2, 3, …).
  • Структура метаданных, модулей. Структура таблиц SQL (1, )
  • Интерфейс, дизайн, эргономика. Картинки (иконки): 16х16 (12000+), , Поздравления.
  • Локализация. Обзор.
  • Работы с оборудованием. Списки совместимости. Связь по TCP. Прошивка, настройка, загрузка/выгрузка. Оборудованием: Сканеры, ККМ, ФР, ТСД, Весы.
  • Мобильная версия 1С
  • Защита кода, конфигураций. Пароль, шифрование. Простые примеры защитыПростая защита флешкой. Обфускация кода,данных.
  • Разработка для типовых конфигураций. Приемы: хранение настроек,  …
  • Печатные формы для типовых. Договор в Word, …
  • Универсальные обработки для типовых конфигураций
  • Универсальный отчет! Как использовать для разработки новых. (1, 2, 3, )
  • Сообщения, чат, уведомления, SMS (1, 2), skype.
  • Автоматизация трудоемких операций пользователей
  • Контроль работы пользователей
  • Производительность труда программиста. Шаблоны, OpenConf для 8-ки.
  • Коммуникация пользователей (аська, форумы, сообщения).
  • Управленческий учет, баланс (баланс, …)
  • Анализ дебиторской задолженности (УТ раз, два, …). БП 12,…
  • Управление продажами (12, 3, …)
  • Штрих-кодирование (ШК), ВК,
  • Поле HTML документа (клик, …)
  • Специфические (для отдельных видов деятельности)
  • Специфические (для конкретных компаний) отчеты, обработки, справочники, документы и т.п.
  • Нормо-часы – Статья. Расценки.
  • Библиотека стандартных подсистем
  • Библиотека “не-стандартных” подсистем (от разработчиков) ;)
  • Командная строка 1С. Статья.
  • Групповая разработка (техническая часть). Работа в команде. Версионирование разработок (статьи). В частности черезхранилище (pdf). Организация веб-доступа к хранилищу. Как сжать (почистить)?
Обмен с другими системами
  • Просто в файлы (загрузки, выгрузки)
    • Текст
    • DBF. Пример чтения.
    • XML. Просмотр большого XML файла в 1С.
    • Excel (код на других языках). Загрузка из Excel (простая, …)
    • выгрузки в Word (код на других языках)
    • Outlook
    • SQL
    • другие СУБД (работа с MySQL, …)
    • прочие
    • CommerceML
  • Банк-клиент (1, 2, 3ускорение, …)
  • Налоговая, ПФР, Контур, Taxcom и т.п.
  • Списки для банков
  • Прочие списки
  • Интернет-магазины
  • Подлючение по ОЛЕ
  • Подлючение по COM
  • Отправка писем. Встроенный функционал, COM-объекты, MAPI.
  • Выгрузки/загруки в КПК
Программирование на других языках (для решения задач 1С)
  • Пакетные файлы (.bat, Батники)
  • Скрипты VBScript (.vbs), JScript (.js). Полезный сайт – script-coding.com. ПО – Среда разработки (типа MS Visual Studio, MS Script Debuger из пакета MS Office и т.п.)
  • SQL запросы
  • Разработка внешних компонент
  • Объектная модель WMI
  • Объектная модель IE
  • Объектная модель WScript (FSO и т.п.)
  • Использование COM объектов (стандартные: Adobe и т.п., уникальные (авторские) разработки)
  • VBA из 1С. Объектная модель Excel, Outlook, Word.
  • карты API Яндекс, Google (ссылка12, …)
  • Интеграция 1С на сайте (посредством php)
  • Среды разработки
  • Разработка под OpenConf, 1с++.
Консалтинг (знание предметной области)
  • Кто такой программист 1С? :) Функциональные обязанности. Как и где их искать? mista, infostart. Анкеты, статьи. Ребята – мы ищем друг друга :)
  • Описание типовых конфигураций. Сравнение (1, 2, ). Выбор.
  • Управленческий консалтинг. Влияние принятия управленческих решений на качество учета в целом. Как навести порядок в учете?
  • Знание бухгалтерского учета в объеме, необходимом и достаточном для работы в программе 1С.
  • Знание налогового учета.
  • Планирование. 1,
  • Бюджетирование.
  • МСФО.
  • Разделение и одновременный учет упр и фин.
  • О программе 1С на рынке программ чета. Что дает 1С бизнесу. Почему именно 1С? Направления развития 1С.
  • Список конкурентов 1С или чем не надо пользоваться. :)  Сравнение 1С с другими программами.
  • Доступная аналитика в 1С.
  • Аналитические статьи, обзоры.
  • Библиотека литературы. Книги.
  • Управленческий учет, Баланс, Коэффициенты.
  • Знание платформы. Хитрости и трюки (дата по GUID, …).
  • Знание типовых конфигураций (функций, архитектуры, особенности/хитрости)
    • По типовым от фирмы 1С
    • Отраслевым решениям. Список.
  • Настройка параметров программ и баз. Учетная политики и т.п.
  • Собственное обучение. Сертификация. Экзамены. Центры обучения и т.п. Где чей сертификатПодготовка.
  • Обучение пользователей. Минимум. Ссылки на видео ролики, инструкции и т.п. Где можно обучить пользователей.
  • Готовые инструкции.
  • Финучет (1, 2, )
  • Список сайтов по 1С
  • Список типовых конфигураций от фирмы 1С
  • Список типовых конфигураций от партнеров фирмы 1С (отраслевые решения) – 1С Совместимо
  • Список уникальных разработок (управление ИТ отделом и т.п.)
  • Обзор SaaS-поставщиков 1С
  • Список книг (по 1С и не только). Описание и рейтинги. Способы приобретения.
Внедрение 1С
  • Внедрение с нуля (учета не было, или работали в Excel).
  • Миграция с другого учетного ПО!,
  • Переход с нетиповых на типовые. С отраслевых решений (например, Камин) или с самописных, или искореженных типовых.
  • Переход на новые версии (6.0, 7.5, 7.7, 8.0, 8.1, 8.2, 8.3). 8.1 -> 8.2,
  • Предпроектное обследовние (пример, ). Анкеты.
  • Управление проектом. Теория. Хроники (от PAVI). Регламент на разработку внутри отдела.
Лицензирование
  • 1С 8, типовые. FAQ от 1С.
  • 1С 8, нетиповые
  • 1С других версий, 7.7 и ранее.
  • Microsoft
  • прочее, смежное с 1С ПО. О программных лицензиях.

Материал с сайта http://blog.prog8.ru/

вторник, 30 октября 2012 г.

Как самому научится программировать в 1С

семинар для программистов 1с

Наша компания проводит бесплатные семинары по изучению программирования в 1С Предприятие 8.

По субботам (по предварительной записи) Вы можете прослушать вводную часть курса "Базовые объекты" совершенно бесплатно.

Бесплатная часть состоит из 2 занятий по 2 академических часа. Всего 4 часа. Поверьте это не мало.

Что вам даст этот семинар?
1. Сдвинет с мертвой точки, дальше сможете самостоятельно заниматся.
2. Понять, нужно ли вам заниматься 1С Программированием.
3. Получить рекомендации по дальнейшему обучению программированию в среде 1С.
4. Вы узнаете, какие материалы лучше приобрести для самостоятельного обучения.
5. Какие курсы лучше подойдут для ваших навыков программирования.

Предварительная запись по телефону 8 920 272 22 72.
Как самому стать программистом 1с, как самому научится программировать в 1с, изучение программирования 1с

Обучение с в туле, обучение программированию 1с тула, 1с тула, 1с предприятие 8.2 тула

Как изучить программу 1С Предприятие?

Компания «» рекомендует обучение в Центрах сертифицированного обучения!  
Центр сертифицированного обучения «Автоматизация» проводит обучение на платформе «1С:Предприятие». Группа наших компаний работаем на рынке более 10 лет. За это время рынок труда пополнился специалистами, уровень компетенции которых не вызывает сомнения не только у представителей фирмы 1С, но и у подавляющего большинства работодателей.


Желаете научится позвоните нам 8(4872 )79-30-60 мы расскажем Вам как это сделать!

Курсы администрирования и программирования 1С

Учебные версии продуктов 1С для начинающих изучение

Учебные версии продуктов 1С и комплекты задач для подготовки к экзаменам
В нашем ЦСО Вы можете приобрести учебные версии продуктов 1С для успешного прохождения обучения и комплекты задач для подготовки к экзаменам 1С:Профессионал и 1С:Специалист. Учебные версии программ могут пригодиться Вам для выполнения домашних заданий, если нет доступа к рабочей версии.
Как стать программистом 1с тула,  как научится работать в 1с тула
Обучение 1с Тула, Курсы для программирования 1с Тула,  ЦСО Тула, как стать программистом 1с


Код Наименование Рекомендованная цена Сделать заказ
4601546089052 1C:Бухгалтерия 8. Учебная версия. 6-е издание 300 руб. Заказать
4601546070821 1С:Предприятие 8.2. Версия для обучения программированию 600 руб. Заказать

четверг, 18 октября 2012 г.

Обучение программированию в 1С с нуля



1С:Предприятие 8 .Обучение программированию с нуля.

Что от вас требуете?
 - Желание. 
 - Усидчивость.

Базовый курс 24 академических часа за 6000 руб.

Во многих учебных центах преподаватели, которые читают подобные курсы не практики,у нас преподаватель со стажем  больше 10 лет.

Есть вопросы звоните 8 920 272 22 72 

1с программирование Тула, курсы 1с Тула, как научится программировать в 1с Тула



воскресенье, 29 июля 2012 г.

Курсы 1С Программирование для Вас в Туле.

- Обучение с нуля.
- Переподготовка с других языков программирования.
- Углубленный курс изучения 1С Предприятия 8.
- Курсы  выходного дня.



Желающие пройти обучении звоните 8 920 272 22 72.

Курсы для программистов 1с в Туле, учимся программировать в 1с Тула, курс от профессионалов и практиков 1с в Туле, Как стать программистом 1с Тула,
1С обучение Тула, 1с Курсы Тула. Трудоустройство после курсов по 1с в Туле при успешной сдачи экзаменов. Хочу изучить 1с Тула Как лучше изучить 1с

четверг, 24 мая 2012 г.

1С:Предприятие. Чем отличается Базовая версия от ПРОФ?

Зная отличии БАЗОВОЙ от ПРОФ вы сможете изрядно сэкономить.


1. Данные версии отличаются ценой
Например: 1С: Бухгалтерия 8 стоит 3300 рублей, а проф версия данной программы 10800 рублей.

2. У базовой версии электронный ключ, в отличие от проф версии.

3. В базовой версии в одной базе Вы можете вести только одно предприятие, в отличие от проф версии, где в одной базе можно вести безграничное количество предприятий

4. Базовая версия не поддерживает сетевой вариант работы

5. Поддержка. При приобретении базовой версии Вы получаете бесплатную поддержку через интернет ВНИМАНИЕ!!!! Если же у Вас ПРОФ версия, то Вам необходимо будет подписываться на ИТС (диски информационно-технического сопровождения). В год за диски вы будите платить от 10800 до 24000 в зависимости от выбранной Вами версии.

6. Доработка. Базовой версии никаких изменений сделать нельзя! Можно только добавлять внешние отчеты, обработки и отчетные формы для документов. Проф версию Вы или программист может доработать под нужды Вашего предприятия, изменить справочники, документы и прочие объекты

понедельник, 23 апреля 2012 г.

Как узнать какой релиз программы и конфигурации 1С Предприятия 8

Чтобы узнать номер релиза платформы и конфигурации 1С Предприятие 8 необходимо войти в программу в режиме «Предприятие» или "Конфигуратор" и выбрать пункт меню «Справка» — «О программе».
Релиз системных файлов (платформы) программы указан в верхней строке этого окна. На рисунке ниже в скобках мы видим цифры: (8.2.15.301), это номер релиза платформы 1С:Предприятие 8.2.
Релиз установленной конфигурации мы также видим в этом окне. Его номер указан в скобках в строке следующей после заголовка «Конфигурация». На нашем примере для версии 8.2 мы видим информацию: “Управление торговлей”, редакция 10.3 (10.3.17.4)

image

понедельник, 16 апреля 2012 г.

Данная версия отчета действует за период начиная с 2011 года. Как бороться?


для 1С 7.7

При запуске формы баланса за 2011 год форма открылась с периодом "Январь - Декабрь 2010 года". При попытке сменить период вывелось сообщение "Данная версия отчета действует за период начиная с 2011 года"

При запуске формы баланса за 2011 год форма открылась с периодом "Январь - Декабрь 2010 года". При попытке сменить период вывелось сообщение "Данная версия отчета действует за период начиная с 2011 года".Это значений для пользователя, т.к. последний раз отчет формировался в 2010 году он автоматом его и выставляет. Для решения этой проблемы достаточно обнулить сохраненные значения для каждого отчета или все настройки пользователя.  Для этого через конфигуратор смотрим рабочий каталог и удаляем из него файлы.


суббота, 14 апреля 2012 г.

Теория управления блокировками в 1С Предприятие 8

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

Описанию возникающих проблем, а также путей их решения в системе 1С:Предприятия 8.1 и посвящена данная статья.

Что такое блокировка

Прежде чем начать изучение механизмов 1С:Предприятия, обеспечивающих конкурентный доступ пользователей к данным, познакомимся с тем, что такое блокировки, когда они возникают и можно ли обойтись без блокировок.

В общем случае блокировка - это информация о том, что данный ресурс захвачен «кем-то», для выполнения какого-то действия.

Рассмотрим простой пример. Продавец продает яблоки. Так получилось, что продавец очень рассеян и ему приходится абсолютно все записывать. По этой же причине все яблоки у него пронумерованны.

Пришел покупатель Иванов и ему понравилось яблоко №4. Он хочет его купить. Иванов достает кошелек и отсчитывает деньги (рис. 1).

clip_image001

Рис. 1. Иванов хочет купить яблоко №4

Тем временем, продавец делает запись в своей книге: «Яблоко №4 - продано Иванову». Эта запись и есть блокировка (рис. 2).

clip_image002

Рис. 2. Продавец «заблокировал» яблоко №4

Обратите внимание, что на самом деле яблоко все еще находится у продавца, Иванов его не купил. Может быть и не сможет купить (например окажется, что не хватает денег). Но у продавца уже записано, что это яблоко нельзя предлагать другим покупателям до тех пор, пока Иванов не завершит процесс покупки. Этот процесс, состоящий из нескольких взаимосвязанных действий (выбор яблока, отсчитывание денег, передача денег продавцу, передача яблока покупателю) называется транзакцией. Блокировка должна быть установлена в момент выбора Ивановым яблока №4 и снята после завершения транзакции покупки.

Тем временем подходит Петров и тоже хочет купить яблоко. Он сможет купить любое яблоко, кроме яблока №4 (рис. 3).

clip_image003

Рис. 3. Петров сможет купить любое яблоко, кроме яблока №4

Таким образом смысл блокировки с том, чтобы запретить некоторые действия над общим ресурсом на некоторое ограниченное время. В данном случае Петрову запрещено выбирать яблоко №4 до тех пор, пока Иванов не завершил свою транзакцию покупки. То есть, Петров находится в состоянии ожидания на блокировке.

Из приведенного примера понятно, что блокировки - это необходимый механизм при конкурентном доступе к общим ресурсам. В самом деле, что бы было, если бы продавец не записал в своей книге, что яблоко из четвертой ячейки нельзя предлагать другим покупателям? Скорее всего произошел бы конфликт между Ивановым и Петровым, возможно при этом «досталось» бы и продавцу. В любом случае, если запись в книге продавца отсутствует, исход данной ситуации становится непредсказуемым. Неизвестно, кому достанется это яблоко, неизвестно у кого окажутся деньги, которые Иванов за него отдал и так далее.

Если же блокировка на яблоко №4 установлена, то это гарантирует однозначный исход: Иванов гарантированно сможет купить яблоко, если у него хватит денег. Если же он откажется от покупки, то только в этом случае яблоко из 4 ячейки сможет купить Петров.

Следует понимать, что в силу различных причин блокировки могут быть как «хорошими» (необходимыми), так и «плохими» (избыточными).

Рассмотрим еще один вариант развития событий, который поясняет откуда берутся «плохие» блокировки.

Покупатель Иванов хочет купить одно яблоко. Он перебирает все яблоки из ящика по одному, выбирая, какое лучше. При этом продавец записывает в своей книге все яблоки, которые понравились Иванову (рис. 4).

clip_image004

Рис. 4. Продавец блокирует все яблоки, которые нравятся Иванову

В это время подходит Петров и не может купить ни одного яблока, потому что они все заблокированы Ивановым (рис. 5).

clip_image005

Рис. 5. Петров не может купить ни одного яблока

Петров ждет некоторое время, обижается и уходит (рис. 6). Это событие соответствует ошибке "Превышение времени ожидания блокировки".

clip_image004[1]

Рис. 6. Петров не дождался и ушел

А Иванов, в результате, выбирает одно единственное яблоко (самое лучшее) и покупает только его (рис. 7).

clip_image006

Рис. 7. Иванов покупает только одно яблоко

Таким образом все остальные яблоки были заблокированы зря. Если бы этих блокировок не было, то Петров, возможно, тоже купил бы яблоко.

В данном случае (в отличие от первого примера) Петров как раз столкнулся с «плохими» (избыточными) блокировками.

Подводя итог сказанному важно отметить, что «хорошие» блокировки обязательно должны присутствовать в прикладном решении. Именно благодаря им обеспечивается предсказуемость действий пользователей, целостность и непротиворечивость данных.

С «плохими» блокировками нужно бороться и в идеале их не должно существовать в прикладном решении. Причины возникновения плохих блокировок могут быть самыми разнообразными: прикладная логика, особенности работы той или иной СУБД и т.д. В данной статье мы познакомимся лишь с механизмами системы 1С:Предприятие 8.1, которые используют блокировки и дадим рекомендации по правильному их использованию. Тема же анализа существующих блокировок и их оптимизации достаточно сложная и объемная, и выходит за рамки данной статьи.

Объектные и транзакционные блокировки

В системе 1С:Предприятие 8 существуют два механизма, при работе которых используется термин блокировка. Зачастую это приводит к путанице и позволяет думать, что речь идет об одних и тех же блокировках или об одном и том же механизме. На самом деле это не так. Каждый из этих механизмов предназначен для обеспечения конкуретной работы пользователей, однако в своей, определенной области, и при этом блокировки, используемые одним и другим механизмами, имеют совершенно различный смысл (рис. 8).

clip_image007

Рис. 8. Объектные и транзакционные блокировки

Логическая модель данных 1С:Предприятия 8 предполагает, что на самом «верхнем» уровне абстрации пользователь имеет дело с объектами системы, как совокупностью неделимых данных. Такими объектами, например, являются элементы справочников, документы и др. Элемент справочника может содержать большое количество реквизитов, несколько табличных частей, но все эти данные необходимо изменять одновременно и согласованно. Механизм объектных блокировок как раз и позволяет осуществлять конкурентный доступ пользователей к данным 1С:Предприятия в терминах объектов информационной базы. Как правило в большинстве случаев это связано с интерактивной работой пользователей в формах: редактирование существующих объектов, удаление, создание новых и др.

В то же время все данные информационной базы хранятся в некоторой СУБД. А любая СУБД должна обеспечивать целостность и непротиворечивость хранимых данных. Для согласованного изменения данных в СУБД используется механизм транзакций, а для обеспечения конкурентного доступа к данным - механизм транзакционных блокировок.

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

Далее рассмотрим работу этих двух механизмов более подробно.

Механизм объектных блокировок

Объектная пессимистическая блокировка

Пессимистическая блокировка объектов базы данных предназначена для того, чтобы запретить изменение данных определенного объекта другими сеансами или данным сеансом до тех пор, пока блокировка не будет снята этим объектом встроенного языка.

В основном механизм пессимистической блокировки используется системой 1С:Предприятие 8.1 для блокировки объектов, редактируемых в форме. В тот момент, когда пользователь начинает модификацию объекта в форме, расширение формы устанавливает пессимистическую блокировку. Если после этого другой пользователь, например, попытается выполнить редактирование того же объекта, ему будет выдано сообщение о том, что не удалось заблокировать объект. Когда пользователь, редактировавший объект, закроет форму объекта, расширение формы снимет пессимистическую блокировку.

Рассмотрим пример. Войдем в прилагаемую к работе информационную базу под пользователем Иванов, откроем форму элемента 1С:Предприятие 8.0. Управление торговлей справочника Номенклатура (код 12) и изменим цену продажи с 420,00на 450,00. Не сохраняя сделанные изменения, войдем в информационную базу еще раз, но теперь под именем пользователя Петров. Откроем форму того же элемента справочника и попробуем изменить значение какого-либо реквизита. Любая попытка изменения приведет к появлению специального окна с сообщением об ошибке (рис. 9):

clip_image008

Рис. 9. Пример работы пессимистической блокировки

Таким образом пессимистическая блокировка гарантирует, что пользователь, начав изменять данные объекта, сможет записать эти изменения в информационную базу.

В то же время, разработчик имеет возможность задействовать рассматриваемый механизм, используя средства встроенного языка. Для того, чтобы установить пессимистическую блокировку объекта, можно использовать метод объектаЗаблокировать().

ВНИМАНИЕ

Важным отличием версии 8.1 платформы 1С:Предприятие является то, что сам по себе факт установки блокировки не препятствует изменению или удалению объекта в базе данных. Поэтому для того, чтобы обеспечить невозможность изменения заблокированного объекта, операции изменения объекта в другом сеансе должна также предшествовать попытка блокировки того же самого объекта. Блокировка заблокированного объекта базы данных вызывает исключение, которое может быть обработано конструкцией Попытка ... Исключение ... КонецПопытки.

Для снятия пессимистической блокировки разработчик может использовать метод объекта Разблокировать(), причем использовать его для того же самого экземпляра объекта, для которого ранее была установлена блокировка.

Рассматривая возможность взаимного влияния механизмов объектных и транзакционных блокировок, напомним, что объектные блокировки не влияют на операции над данными и на процесс течения транзакций (обратите внимание, на рис 8 они расположены на разных уровнях работы с данными). Если блокировка объекта вызвала исключение, то оно, как было указано выше, может быть обработано разработчиком конфигурации и не приведет к обязательному откату транзакции. С другой стороны, блокировки объектов, установленные в течение транзакции, сохраняются при фиксации транзакции и снимаются при откате транзакции.

Объектная оптимистическая блокировка

Оптимистическая блокировка запрещает запись объекта в базу данных, если после считывания объекта он был изменен в базе данных другими сеансами или другими программными объектами этого же сеанса.

Фактически, оптимистическая блокировка представляет собой проверку, которая выполняется перед записью объекта в базу данных. Эта проверка построена на анализе номера версии объекта, хранящейся в базе данных и номера версии, помещенной в память компьютера в момент считывания данных из информационной базы. Если при записи объекта номера его версий отличаются, то будет выдано предупреждение о том, что версия объекта изменилась или он был удален, то есть сработает оптимистическая блокировка.

Рассмотрим пример. Откроем два сеанса работы с прилагаемой к работе информационной базой: один под пользователем Иванов, а другой - под пользователем Петров. В обоих сеансах откроем откроем форму элемента Управление торговлейсправочника Номенклатура (код 12). Теперь в сеансе, открытом от имени пользователя Иванов, изменим цену продажи с 420,00 на 450,00 и запишем сделанные изменения. После этого, в сеансе, открытом от имени пользователя Петровпопробуем изменить значение какого-либо реквизита. Любая попытка изменения приведет к появлению другого окна с сообщением об ошибке (рис. 10):

clip_image009

Рис. 10. Пример работы оптимистической блокировки

Таким образом оптимистическая блокировка гарантирует, что пользователь изменяет актуальные данные объекта, которые хранятся в информационной базе, а не какой-то их предыдущий вариант.

Механизм транзакционных блокировок

Общие сведения о транзакциях и блокировках СУБД

Прежде чем перейти к рассмотрению механизмов платформы 1С:Предприятие, познакомимся в общих чертах с понятиями, которые будут использованы далее.

Понятие транзакционной блокировки неразрывно связано с понятием транзакции.

Транзакция - это неделимая, с точки зрения воздействия на базу данных, последовательность операций манипулирования данными, выполняющаяся по принципу «все или ничего», и переводящая базу данных из одного целостного состояния в другое целостное состояние. Если по каким-либо причинам одно из действий транзакции невыполнимо или произошло какое-либо нарушение работы системы, база данных возвращается в то состояние, которое было до начала транзакции (происходит откат транзакции).

Возможные проблемы при многопользовательском доступе к одним и тем же данным

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

Как известно, при одновременном чтении и изменении одних и тех же данных конкурирующими транзакциями могут возникнуть следующие проблемы одновременного доступа:

· Проблема потерянного изменения (англ. The Lost Update Problem) - если две транзакции изменяют одни и те же данные, взяв в качестве первоисточника начальное значение этих данных, то в системе останутся изменения внесенные той транзакцией, которая записала свои изменения последней, поскольку эти изменения заменят собой все изменения, внесенные до этого.

Пример. Рассмотрим следующий пример. Допустим в справочнике Номенклатура, Транзакция №1 обратилась к элементу 1С:Предприятие 8.0. Управление торговлей и решила изменить значение реквизита ЦенаПродажи с 420 на 450. Одновременно Транзакция №2 решила у этого же товара изменить значение реквизита ЕдиницаИзмерения со Штука на Коробка. Распределение по времени описанных действий показано на рис. 11. Таким образом, в элементе справочника остались только те изменения, которые сделала Транзакция №2.

Вывод. Нельзя одновременно изменять одни и те же данные;

clip_image010

Рис. 11. Иллюстрация проблемы потерянного изменения

· Проблема «грязного» чтения (англ. The Uncommitted Dependency Problem) - если одна транзакция начнет считывать некоторые данные не дождавшись окончания внесения изменений, вносимых в эти данные другой транзакцией, то достаточно вероятен случай, когда прочитанные данные будут содержать неверную информацию.

Пример. Вернемся к примеру, рассмотренному выше. Допустим в справочнике Номенклатура, Транзакция №1 обратилась к элементу1С:Предприятие 8.0. Управление торговлей и изменила значение реквизита ЦенаПродажи с 420 на 450. Не дождавшись фиксации изменений, Транзакция №2 использовала значение реквизита для определения суммы продажи. Однако, первая транзакция решила не сохранять внесенные изменения (откат транзакции) и восстановила старые данные. Графическое представление действий транзакций показано на рис. 12. Таким образом, Транзакция №2 в своих расчетах использовала данные, не существующие в системе.Вывод. Нельзя читать уже измененные, но еще не записанные данные.

clip_image011Рис. 12. Иллюстрация проблемы «грязного» чтения

· Проблема неповторяемого чтения (англ. The Inconsistent Analysis Problem) - если одна транзакция несколько раз считывает одни и те же данные, а вторая - вносит изменения в эти данные между циклами чтения данных первой транзакции, то при повторном считывании первая транзакция может получить другой набор данных.

Пример. Допустим, в нашем примере, Транзакция №1 два раза подряд обращается к элементу справочника 1С:Предприятие 8.0. Управление торговлей и каждый раз считывает значение реквизита ЦенаПродажи. Если в промежуток между первым и вторым чтением вклинится Транзакция №2 и изменит значение этого реквизита, то в результате получится, что первая транзакция работает с данными, которые с ее точки зрения самопроизвольно изменяются. Графическое представление данной проблемы показано на рис. 13.

Выводы. Нельзя повторно читать измененные и записанные данные, если эти же самые данные уже были прочитаны до внесения в них изменений;

clip_image012

Рис. 13. Иллюстрация проблемы неповторяемого чтения

· Проблема чтения фантомов (англ. The Phantom Read Problem) - если первая транзакция считывает данные и потом на их основе осуществляет определенные действия, а вторая транзакция в этот момент добавляет в эти данные новую информацию, то как и в предыдущем случае это может привести к некорректному результату.

Пример. Допустим, компания занимается продажей товаров и состоит из нескольких отделов. В случае, когда объем продаж сотрудников одного отдела превышает 1000 рублей, то каждый сотрудник отдела получает премию 20 % от суммы своих продаж. В противном случае, размер премии составляет 10 %. Очевидно, что процесс начисления премии сотрудникам каждого отдела будет состоять из нескольких операций:

· получения общей суммы продаж по отделу в целом путем суммирования отдельных продаж по каждому из сотрудников;

· определения на основании полученных данных процента премии;

· расчета суммы премии для каждого из сотрудников отдела.

Предположим, что данные о продажах вводит Транзакция №2, а размер премии рассчитывает Транзакция №1. Тогда при одновременной работе транзакций может возникнуть ситуация, показанная на рис. 14. Таким образом, Транзакция №1 в двух одинаковых выборках строк получил разные результаты.

Выводы. Нельзя вводить новые данные (удалить имеющиеся), если они могут попасть в уже один раз прочитанные данные при повторном чтении.

clip_image013

Рис. 14. Иллюстрация проблемы фантомов

Строго говоря, список вышеперечисленных проблем не является окончательным.

Уровни изоляции транзакций

Итак, ради увеличения производительности системы мы должны допустить параллельное выполнение транзакций. При этом мы так же должны обеспечить необходимую нам степень целостности данных (то есть, ограничить параллельность транзакций при работе с одними ресурсами). Строгость этих ограничений может быть различной, в зависимости от решаемой задачи. Поэтому нам необходим механизм гибкой настройки этих ограничений. В современных СУБД такая возможность реализуется путем применения уровней изоляции транзакций. Например, MS SQL Server 2000 позволяет использовать следующие уровни изоляции транзакции:

· READ UNCOMMITED - незавершенное чтение. Низший уровень изоляции, обеспечивает максимальную параллельность выполнения транзакций. Данный уровень защищает изменяемые мной данные от изменений, которые могут внести конкурирующие транзакции. Если другой транзакции необходимо изменить те же самые данные, то она должна ожидать завершения изменения данных моей транзакцией. Однако чтение данных разрешено. Таким образом этот уровень изоляции допускает чтение незавершенных изменений данных.

· READ COMMITED - обеспечивает запрет «грязного» чтения. Если моя транзакция начала изменять данные, то конкурирующая транзакция не может не только измененить, но даже прочитать их до завершения моих изменений. После того, как мои изменения закончены, конкурирующие транзакции могут читать данные, не дожидаясь окончания моей транзакции в целом. Таким образом существует проблема неповторяемого чтения.

· REPEATABLE READ - обеспечивает повторяемость чтения данных. Если моя транзакция начинает читать данные, то другая транзакция не может их изменить до окончания моей транзакции.

· SERIALIZABLE - последовательное выполнение. Этот уровень изоляции является максимальным и обеспечивает полную изоляцию транзакций друг от друга. Решаются все рассмотренные проблемы, включая проблему «фантомов».

В зависимости от используемого уровня изоляции, СУБД накладывает различные типы блокировок на различные объекты базы данных на различное время.

Режим автоматических блокировок

Режим автоматических блокировок в 1С:Предприятии 8.1 полностью аналогичен механизму транзакционных блокировок, использовавшемуся в версии 8.0. В этом режиме 1С:Предприятие целиком «полагается» на возможности, предоставляемые СУБД (рис. 15).

clip_image014

Рис. 15. Автоматические блокировки в транзакции 1С:Предприятия 8

Такой подход позволяет разработчику не задумываться о достаточно сложных вопросах блокирования нужных данных в транзакции. Однако СУБД не имеет информации о логической структуре данных 1С:Предприятия, и платформе приходится использовать достаточно высокие уровни изоляции транзакций СУБД для того, чтобы обеспечить целостность и непротиворечивость данных (табл. 3): Repeatable Read и Serializable для MS SQL Server, Serializable для IBM DB2 и блокировка таблиц целиком для PostgreSQL.

Таблица 3. Блокировки СУБД, используемые в режиме автоматических блокировок в транзакции

 

СУБД

 

Файловая база данных

MS SQL Server

IBM DB2

PostgreSQL

Вид блокировок

Таблиц

Записей

Записей

Таблиц

Уровень изоляции транзакций

Serializable

Repeatable Read или Serializable

Serializable

Read Committed

Зачастую такой подход приводит к возникновению «плохих» (избыточных) блокировок и не позволяет достичь желаемой параллельности работы пользователей. В клиент-серверном варианте блокировка данных происходит на уровне записей, однако может быть заблокирована и вся таблица целиком (например, в результате выбора СУБД неоптимального плана выполнения запроса). Тип блокировок, устанавливаемых в том или ином случае, зависит от вида операции, используемого 1С:Предприятием уровня изоляции транзакций и определяется внутренними механизмами самой СУБД (например, MS SQL Server).

Режим управляемых блокировок

В 1С:Предприятии версии 8.1 реализован дополнительный режим работы, позволяющий использовать собственный менеджер транзакционных блокировок 1С:Предприятия, независимый от используемой СУБД (рис. 16).

clip_image015

Рис. 16. Управляемые блокировки в транзакции 1С:Предприятия 8.1

При работе в этом режиме система использует гораздо более низкий уровень изоляции транзакций для MS SQL Server и IBM DB2, и блокировку на уровне записей для PostgreSQL (см. таблицу 3). Это позволяет достичь более высокой параллельности работы пользователей.

Таблица 3. Блокировки СУБД, используемые в режиме управляемых блокировок в транзакции

 

СУБД

 

Файловая база данных

MS SQL Server

IBM DB2

PostgreSQL

Вид блокировок

Таблиц

Записей

Записей

Записей

Уровень изоляции транзакций

Serializable

Read Committed

Read Committed

Read Committed

Однако этот уровень изоляции транзакций СУБД уже не может сам по себе обеспечить целостность и непротиворечивость данных во всех случаях. Поэтому 1С:Предприятие 8.1 при модификации данных методами встроенного языка (например, метод Записать() у объектных данных) устанавливает собственные управляемые блокировки в транзакции, которые обрабатываются собственным менеджером транзакционных блокировок. Эти блокировки также могут быть установлены и разработчиком самостоятельно в тех местах кода, где требуется обеспечить неизменность считываемых в транзакции данных (разделяемая блокировка) или запретить чтение данных другими транзакциями (исключительная блокировка).

Управляемые блокировки 1С:Предприятия учитывают логическую структуру прикладного решения поэтому позволяют максимально точно блокировать необходимые области данных (в отличие от использовавшихся ранее блокировок СУБД, которым не известна логическая структура системы). Таким образом менеджер управляемых блокировок позовляет максимально избежать возникновения «плохих» (избыточных) блокировок, блокируюя только действительно необходимые области данных.

В результате любой запрос к данным прежде всего обрабатывается собственным менеджером транзакционных блокировок 1С:Предприятия 8.1 (см. рис. 16). Если на уровне 1С:Предприятия 8.1 конфликт управляемых блокировок не обнаруживается, то запрос передается далее, на исполнение СУБД. СУБД также использует собственный механизм блокировок для определения конфликтующих транзакций, но уже с более низким уровнем изоляции транзакций, чем в режиме автоматических блокировок.

Установка режима управления блокировками для объектов конфигурации

В структуре объектов конфигурации существует несколько возможностей для задания режима управления блокировками.

Прежде всего существует свойство Режим управления блокировкой данных самой конфигурации (рис. 17).

clip_image016

Рис. 17. Список значений свойства «Режим управления блокировкой данных» в палитре свойств Конфигурации

При выборе значений Автоматический или Управляемый режим блокировок при чтении или записи данных любого объекта конфигурации будет определяться именно этим выбранным значением.

Например, если установлен режим Автоматический, то при записи, скажем, любого элемента справочника, будут использоваться автоматические блокировки, устанавливаемые СУБД. Собственнный менеджер блокировок задействован не будет. Поведение системы будет полностью аналогичным поведению версии 8.0.

Если же установлен режим Управляемый, то, независимо от того, какие режимы управления блокировками установлены для конкретных объектов конфигурации (об этом смотри далее), при записи, скажем, документа система всегда будет самостоятельно устанавливать необходимые управляемые блокировки, которые будут обрабатываться собственным менеджером транзакционных блокировок. Этот режим предназначен для работы всей конфигурации только с управляемыми блокировками в транзакции.

Если же для свойства конфигурации выбран режим Автоматический и управляемый, то для конкретного объекта конфигурации режим блокировки будет определяться значением свойства Режим управления блокировкой данных самого объекта конфигурации (рис. 18).

clip_image017

Рис. 18. Список значений свойства «Режим управления блокировкой данных» в палитре свойств объекта конфигурации

Этот режим предназначен для постепенного или частичного перевода конфигурации в режим управляемых блокировок. Он позволяет отдельным объектам метаданных работать с управляемыми блокировками (например, наиболее «проблемным» документам и регистрам), в то время как остальные объекты работают в режиме автоматических блокировок.

Важной особенностью работы в режиме Автоматический и управляемый является то, что не во всех ситуациях работа с данными объекта будет выполняться именно в том режиме, который для него указан. Рассмотрим эту особенность подробно.

Внутри одной транзакции, которая начата и не завершена 1С:Предприятием, может быть начата еще одна (или несколько) транзакций. Такая логика работы обеспечивается платформой автоматически, а также поддерживается средствами встроенного языка.

В 1С:Предприятии 8.1 при начале каждой транзакции явно (если она начата из встроенного языка) или неявно (если она начата в результате действий самой системы) указывается режим управления блокировками в данной транзакции (автоматический или управляемый). Таким образом может оказаться, что первая (объемлющая) транзакция открыта в одном режиме, а вторая - в другом режиме управления блокировками. Всего может быть четыре различных сочетания, которые представлены в таблице 3.

Таблица 3. Сочетания режимов управления блокировками в транзакции

Режим существующей транзакции

Режим начинаемой транзакции

Результат

Автоматический

Автоматический

Начинаемая транзакция будет выполнена в автоматическом режиме

Управляемый

Управляемый

Начинаемая транзакция будет выполнена в управляемом режиме

Автоматический

Управляемый

Начинаемая транзакция будет выполнена в автоматическом режиме

Управляемый

Автоматический

Будет вызвана исключительная ситуация

Указанная ранее особенность проявляется в последних двух строках таблицы. Если существующая транзакция начата в автоматическом режиме, то начинаемая транзакция таже будет выполнена в автоматическом режиме, даже в том случае, если явно (во втроенном языке) или неявно (в свойствах объекта конфигурации) для нее установлен управляемый режим блокировок.

Если же существующая транзакция начата в управляемом режиме, то начинаемая транзакция может быть выполнена только в том случае, если для нее также указан управляемый режим. Если для нее указан автоматический режим - будет вызвана исключительная ситуация.

Разберем эту особенность на двух примерах.

Например, запись элемента справочника выполняется из встроенного языка внутри транзакции, открытой разработчиком. В этом случае «первой» (явной) транзакцией будет транзакция, инициированная разработчиком, а «второй» (неявной) будет транзакция, открываемая платформой при выполнении метода Записать() объекта справочника.

Явная транзакция открывается разработчиком с помощью метода встроенного языка НачатьТранзакцию(). В отличие от версии 8.0 этот метод имеет параметр БлокировкаДанных, который указывает какой режим управления блокировками будет использоваться в данной транзакции. По умолчанию значение этого параметра равно Автоматический. Поэтому, если разработчик использует значение этого параметра по умолчанию, то независимо от того, какой режим установлен в свойствах записываемого справочника, его запись будет выполнена в автоматическом режиме (см. табл. 3, 1 и 3 строки).

Если же разработчик открывает транзакцию в управляемом режиме, то он должен быть уверен в том, что для записываемого в этой транзакции справочника, в свойствах метаданных указан управляемый режим блокировок в транзакции. В противном случае при записи элемента справочника будет вызвана исключительная ситуация (см. табл. 3, 2 и 4 строки).

Рассмотрим другой пример - интерактивное проведение документа, который выполняет движения по регистру накопления. В этом случае «первой» (неявной) транзакцией будет транзакция, открываемая системой при записи документа, а «второй» (также неявной) будет транзакция, открываемая системой при записи набора записей регистра накопления.

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

Если же для документа установлен управляемый режим блокировок в транзакции, то для регистра накопления таже должен быть установлен управляемый режим, иначе при проведении документа будет вызвана исключительная ситуация.

Из этих примеров можно сделать следующий общий вывод. Если, например, стоит задача повысить параллельность работы при проведении отдельного документа, не переводя при этом всю конфигурацию в управляемый режим, то последовательность действий должна быть следующей:

· свойство конфигурации Режим управления блокировкой данных необходимо установить в значение Автоматический и управляемый;

· свойство Режим управления блокировкой данных объекта метаданных документ необходимо установить в значение Управляемый;

· у всех регистров, по которым данный документ выполняет движения, следует установить свойство Режим управления блокировкой данных в значение Управляемый;

· проанализировать процедуру проведения документа на предмет наличия:

o явных вызовов транзакций

o неявных вызовов транзакций, которые выполняются системой при модификации данных каких-либо объектов конфигурации

· для найденных явных и неявных вызовов транзакций обеспечить их выполнение в управляемом режиме

o для явных вызовов - параметр метода НачатьТранзакцию();

o для неявных вызовов - свойство Режим управления блокировкой данных модифицируемого объекта конфигурации;

· в теле процедуры проведения документа установить необходимые управляемые блокировки (об этом см. далее).

Установка управляемых блокировок

Средствами встроенного языка установка управляемых блокировок внутри явной или скрытой (неявной) транзакции происходит с помощью специального объекта БлокировкаДанных, описание доступных свойств и методов которого можно посмотреть в синтакс-помощнике в ветви Общие объекты (рис. 19).

clip_image018

Рис. 19. Набор свойств и методов объекта «БлокировкаДанных» доступных в Синтакс-помощнике

Новый экземпляр данного объекта может быть создан с помощью одноименного конструктора и представляет собой коллекцию элементов блокировки данных. Изначально эта коллекция пуста и задача разработчика состоит в добавлении в эту коллекцию некоторого количества элементов блокировки.

При добавлении нового элемента блокировки для него необходимо указать пространство блокировок, которое будет блокировать данный элемент. Пространства блокировок определены в платформе 1С:Предприятия 8.1 и соответствуют структуре прикладных объектов конфигурации. Допустимы следующие имена пространств блокировок и имена полей пространств блокировок (табл. 9):

Имя пространства блокировок

Поля пространства блокировок

Справочник.<имя>

Ссылка

Документ.<имя>

Ссылка

ПланОбмена.<имя>

Ссылка

ПланСчетов.<имя>

Ссылка

БизнеcПроцесс.<имя>

Ссылка

Задача.<имя>

Ссылка

ПланВидовРасчета.<имя>

Ссылка

ПланВидовХарактеристик.<имя>

Ссылка

РегистрСведений.<имя>.НаборЗаписей - только для регистра сведений, подчиненного регистратору

Регистратор

РегистрСведений.<имя>

Период - если есть;
<имя измерения>

РегистрНакопления.<имя>.НаборЗаписей

Регистратор

РегистрНакопления.<имя>

Период;
<имя измерения>

РегистрБухгалтерии.<имя>.НаборЗаписей

Регистратор

РегистрБухгалтерии.<имя>

Период;
<вид движения> - значение системного перечисления ВидДвиженияБухгалтерии;
Счет - обязательное поле;
Субконто;
<вид субконто>;
<имя измерения>

РегистрРасчета.<имя>.НаборЗаписей

Регистратор

РегистрРасчета.<имя>

ПериодРегистрации;
ПериодДействия;
<имя измерения>

Перерасчет.<имя>.НаборЗаписей

ОбъектПерерасчета

Перерасчет.<имя>

ВидРасчета

Последовательность.<имя>.НаборЗаписей

Регистратор

Последовательность.<имя>

<имя измерения>

Константа.<имя>

 

Как видно из таблицы, для объектных данных (справочник, документ и др.) определено единственное пространство блокировки - сам объект данных. Для необъектных данных (например, регистры) определено по два пространства блокировок, которые имеют разный логический смысл.

Пространство блокировок с суффиксом НаборЗаписей используется в тех случаях, когда необходимо заблокировать сами записи данного объекта (например, при добавлении новых записей).

Пространство блокировок без суффикса используется тогда, анализируются некоторые данные этого объекта (например, остатки регистра), или когда выполняются какие-либо операции, приводящие к изменению существующих данных объекта (например, восстановление границы последовательности).

После того, как элемент блокировки, соответствующий некоторому пространству блокировок, добавлен, следует установить для этого элемента режим блокировки (разделяемая или исключительная) и определить значения полей блокировки, чтобы указать, какие же именно «записи» будут заблокированы (для каждого пространства блокировок в платформе определены имена полей, значения которых могут задаваться при установке тех или иных блокировок).

ВНИМАНИЕ

Следует понимать, что, в данном случае речь не идет о реальных записях базы данных. Несмотря на то, что управляемые блокировки описываются в терминах объектов метаданных и их полей, эти блокировки никак не связаны с реальной структурой хранения данных 1С:Предприятия в СУБД. Это всего лишь записи о том, что заблокировано «нечто».

Иногда можно провести аналогию между управляемыми блокировками и реальными записями СУБД. Например, для объектных данных блокировка объекта с указанной ссылкой будет «соответствовать» блокировке всех записей, содержащих указанную ссылку, во всех таблицах этого объекта метаданных (в основной таблице и в таблицах его табличных частей).

Однако в других случаях провести такую аналогию достаточно затруднительно, да и не нужно. Например, блокировка регистра бухгалтерии с указанием значения вида субконто. Достаточно понимать, что накладывая такую блокировку мы запрещаем другим транзакциям каким-либо образом изменять «записи» регистра бухгалтерии, у которых значение вида субконто равно указанному нами. Как при этом данное условие «проецируется» на реальную структуру данных регистра бухгалтерии - для нас совершенно не важно.

При установке новых блокировок менеджер анализирует имеющиеся блокировки. Если оказывается, что «нечто», что мы пытаемся заблокировать, уже заблокировано ранее, сравниваются режимы существующей и новой блокировок. Если режимы совместимы - новая блокировка устанавливается. Если режимы не совместимы - новая блокировка ожидает снятия существующей блокировки.

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

Существует два способа задания условий на поля пространств блокировки:

· с помощью явного задания имени поля и его значения;

· с помощью указания источника данных, содержащего необходимые значения

При явном задании имени поля и его значения необходимо использовать метод УстановитьЗначение() объекта ЭлементБлокировкиДанных. В этом случае имя и значение указывают в качестве параметров метода, например так, как показано в листинге 1:

Листинг 1. Пример установки условия блокировки записей с помощью явного указания имени поля и его значения

// Создать объект блокировка данных

БлокировкаДанных = Новый БлокировкаДанных;

// Добавить новый элемент блокировки, блокирующий «нечто» в данных регистра накопления Остатки номенклатуры

ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиНоменклатуры");

// Установить режим блокировки - исключительный. Другие транзакции, устанавливающие управляемые

// блокировки, не смогут даже начать чтение этих данных

ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

// Указать, что именно мы блокируем в данных регистра Остатки номенклатуры - все «записи», у которых

// значение измерения Склад равно значению, содержащемуся в переменной Склад

ЭлементБлокировки.УстановитьЗначение("Склад", Склад);

Для значений типа Дата или Число в качестве значения может быть задан некоторый диапазон значений. Диапазон значений передается методу с помощью объекта встроенного языка - Диапазон. Данный объект позволяет задать верхнюю и нижнюю границы диапазона, причем в диапазон включаются и границы диапазона (листинг 2).

Листинг 2. Пример установки условия блокировки записей с помощью задания диапазона

// Создать объект блокировка данных

БлокировкаДанных = Новый БлокировкаДанных;

// Добавить новый элемент блокировки, блокирующий «нечто» в данных регистра накопления Продажи

ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.Продажи");

// Установить режим блокировки - разделяемый. Эти данные гарантировано не будут изменены другими

// транзакциями до окончания существующей транзакции

ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;

// Указать, что именно мы блокируем в данных регистра Продажи - все «записи», у которых

// значение измерения Контрагент равно значению, содержащемуся в переменной Контрагент

ЭлементБлокировки.УстановитьЗначение("Контрагент", Контрагент);

// Создать объект Диапазон, описывающих интервал от начала месяца, к которому принадлежит указанная дата,

// до указанной даты

Диапазон = Новый Диапазон(НачалоМесяца(Дата), Дата);

// Указать, что именно мы блокируем в данных регистра Продажи - все «записи», у которых

// значение измерения Контрагент равно значению, содержащемуся в переменной Контрагент,

// и значение поля Период содержится в указанном диапазоне

ЭлементБлокировки.УстановитьЗначение("Период", Диапазон);

При указании источника данных сначала необходимо задать свойство ИсточникДанных объекта ЭлементБлокировкиДанных, после чего, используя метод ИспользоватьИзИсточникаДанных(), настроить соответствие полей области блокировки данных полям источника данных (листинг 3).

Листинг 3. Пример установки условия блокировки записей с помощью источника данных

// Создать объект блокировка данных

БлокировкаДанных = Новый БлокировкаДанных;

// Добавить новый элемент блокировки, блокирующий «нечто» в данных регистра накопления Остатки номенклатуры

ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиНоменклатуры");

// Установить режим блокировки - исключительный. Другие транзакции, устанавливающие управляемые

// блокировки, не смогут даже начать чтение этих данных

ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

// Указать, что именно мы блокируем в данных регистра Остатки номенклатуры - все «записи», у которых

// значение измерения Склад равно значению, содержащемуся в переменной Склад

ЭлементБлокировки.УстановитьЗначение("Склад", Склад);

// Указать источник данных, который содержит данные для установки ограничений на другие поля этого

// элемента блокировки - в данном случае таблица значений СписокНоменклатуры

ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;

// Указать, что именно мы блокируем в данных регистра Остатки номенклатуры - все «записи», у которых

// значение измерения Склад равно значению, содержащемуся в переменной Склад,

// и у которых значение измерения Номенклатура равно какому-либо значению, содержащемуся в колонке

// Номенклатура указанного источника данных

ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");

В качестве источника данных можно указывать результат запроса, табличную часть, набор записей или таблицу значений. При установке соответствия полей, именами полей источника будут являться имена колонок результата запроса, имена реквизитов табличной части, имена измерений или имена колонок таблицы значений соответственно. Заметим, что объект Диапазон также может являться значением поля источника данных.

Для установки всех созданных нами блокировок используется метод объекта БлокировкаДанных - Заблокировать(). На рисунке 20 показано действие данного метода в случае использования его внутри транзакции и вне ее.

clip_image019

Рис. 20. Схема вызова метода «Заблокировать()» объекта «БлокировкаДанных»

Как следует из рисунка, если этот метод выполняется внутри транзакции (явной или неявной), то блокировки устанавливаются в момент вызова метода. При окончании транзакции они будут сняты автоматически. Если же метод Заблокировать()выполняется вне транзакции, то блокировки установлены не будут.

Рекомендации по модификации конфигураций при переходе к режиму управляемых блокировок

При переводе созданных ранее прикладных решений с версии 1С:Предприятие 8.0 на версию 1С:Предприятие 8.1 они требуют определенной степени доработки с точки зрения перехода к работе в режиме управляемых блокировок. Дадим ряд рекомендаций, позволяющих определить последовательность действий разработчика в случае реализации вышеупомянутого перевода:

· Конвертируем конфигурацию из версии 8.0 в конфигурацию версии 8.1. Режим управляемых блокировок - автоматический.

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

· Постепенно переводим конфигурацю в управляемый режим. Устанавливаем свойство Режим управления блокировкой данных всей конфигурации в целом в режим Автоматический и управляемый.

· Для указанных в списке видов документов переводим свойство Режим управления блокировкой данных в значение Управляемый. Также в управляемый режим переводим все регистры, по которым эти документы выполняют движения и все транзакции (явные и неявные), открываемые в процессе проведения документа.

· Анализируем тексты модулей каждого из указанных видов документов. Нас интересуют операции чтения данных. Причем не все, а только те, где выполняется чтение некоторых данных, на основании которых затем модифицируются эти же, или другие данные. Очевидно, что читаемые данные в этом случае не должны быть изменены до окончания транзакции проведения документа, а значит перед чтением их требуется заблокировать.

· Устанавливаем управляемые блокировки на найденные нами данные. При этом разделяемая блокировка устанавливается для того, чтобы данные не были изменены другими транзакциями. Исключительная блокировка, помимо этого, обеспечивает запрет не только изменения этих данных, но даже их чтения другими транзакциями, устанавливающими управляемые блокировки. Можно сказать, что исключительная управляемая блокировка является средством борьбы с конфликтами блокировок (deadlock) и может использоваться аналогично ключевому слову ДЛЯ ИЗМЕНЕНИЯ языка запросов в режиме автоматических блокировок.

ВНИМАНИЕ

В режиме управляемых блокировок, за счет использования другого уровня изоляции транзакций СУБД, конструкция ДЛЯ ИЗМЕНЕНИЯязыка запросов не работает. Таким образом, если в транзакции встречаются запросы, содержащие эту конструкцию, перед их выполнением необходимо устанавливать исключительную управляемую блокировку на читаемые данные. Это позволит в управляемом режиме обеспечить поведение, аналогичное поведению в автоматическом режиме.

Следует помнить, что чтение данных другими транзакциями будет невозможно только в том случае, если в других транзакциях устанавливаются несовместимые управляемые блокировки. Если управляемые блокировки в других транзакциях не устанавливаются, то чтение будет возможно. Это аналогично тому, как конструкция ДЛЯ ИЗМЕНЕНИЯ препятствует чтению данных не любыми запросами, а только теми, которые тоже используют конструкцию ДЛЯ ИЗМЕНЕНИЯ.

· При установке управляемой блокировки необходимо стремиться, чтобы блокировка была установлена только на те записи, которые будут обработаны системой в результате отработки программного кода. Другими словами, при установке управляемой блокировки желательно ставить условия на те же самые поля и по тем же самым значениям, которые были указаны, например, в тексте запроса к данным информационной базы. Например, см. текст листинга 4.

В качестве примера, приведем фрагмент программного кода из текста обработчика ОбработкаПроведения(), расположенного в модуле документа РасходнаяНакладная (листинг 4). При выполнении указанного программного кода система, используя механизм запросов, сначала читает информацию из регистра накопления ОстаткиНоменклатуры, а потом записывает в тот же самый регистр вновь сформированные данные. Согласно нашим рекомендациям, мы должны установить на записи регистра исключительную блокировку, запрещающую другим транзакциям, в которых устанавливаюся управляемые блокировки, не только запись, но и чтение, изменяемых при проведении накладной записей. В данном случае исключительная блокировка нужна для предотвращения возможного конфликта блокировок (deadlock).

Разбирая программный код, обратите внимание на соответствие условий при блокировке данных и в тексте запроса.

Листинг 4. Пример установки исключительной блокировки при проведении документа «РасходнаяНакладная»

БлокировкаДанных = Новый БлокировкаДанных;

// Выбрать пространство блокировок РегистрНакопления.ОстаткиНоменклатуры, т.к. мы собираемся анализировать

// остатки регистра

ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиНоменклатуры");

ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

// Заблокировать «записи» с указанным значением измерения склад, т.к. в запросе есть следующее условие:

// ... И Склад = &Склад) ...

ЭлементБлокировки.УстановитьЗначение("Склад", Склад);

// Заблокировать «записи» со значениями номенклатуры из табличной части, соответствующими условию

// ... РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Услуга = ЛОЖЬ ...

// эти данные необходимо получить запросом к табличной части

ЗапросИсточник = Новый Запрос;

ЗапросИсточник.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ

| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура

|ИЗ

| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры

|ГДЕ

| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка

| И РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Услуга = ЛОЖЬ";

ЗапросИсточник.УстановитьПараметр("Ссылка", Ссылка);

ИсточникНоменклатуры = ЗапросИсточник.Выполнить();

ЭлементБлокировки.ИсточникДанных = ИсточникНоменклатуры;

ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");

БлокировкаДанных.Заблокировать();

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

. . . . . . . . . .

|ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(&МомВремени,

|Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ

|РасходнаяНакладнаяСписокНоменклатуры.Номенклатура

|ИЗ

|Документ.РасходнаяНакладная.СписокНоменклатуры КАК

|РасходнаяНакладнаяСписокНоменклатуры

|ГДЕ

|РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка

|И РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Услуга = ЛОЖЬ)

|И Склад = &Склад) КАК ОстаткиНоменклатурыОстатки

. . . . . . . . . .

|";

. . . . . . . . . .

Пока Выборка.Следующий() Цикл

. . . . . . . . . .

// регистр ОстаткиНоменклатуры Расход

Движение = Движения.ОстаткиНоменклатуры.Добавить();

Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

Движение.Период = Дата;

Движение.Номенклатура = Выборка.Номенклатура;

Движение.Склад = Склад;

Движение.Количество = Выборка.Количество;

СуммаСписания = ?(Выборка.КоличествоОстаток = Выборка.Количество,

Выборка.СуммаОстаток,

Выборка.СуммаОстаток / Выборка.КоличествоОстаток * Выборка.Количество);

Движение.Сумма = СуммаСписания;

КонецЦикла;

Движения.ОстаткиНоменклатуры.Записать();

Обратите внимание, что при создании источника данных для установки блокировок по номенклатуре мы использовали результат запроса к табличной части. Казалось бы, в качестве источника данных можно было просто использовать табличную часть (ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры), но при этом мы бы заблокировали лишние данные, ведь нас интересует только та номенклатура из табличной части, которая не является услугой (РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Услуга = ЛОЖЬ). Этот момент как раз хорошо иллюстрирует тот факт, что к установке управляемых блокировок нужно относиться внимательно и не устанавливать «плохих» (избыточных) блокировок.

Теперь расмотрим подробнее вопрос необходимости установки именно исключительной управляемой блокировки.

Если бы мы не использовали никакой управляемой блокировки, то наш запрос, читающий данные, начал бы выполняться в любом случае. После его окончания (еще до окончания транзакции!) СУБД сняла бы блокировку с прочитанных данных. Это значит, что другая транзакция тут же могла бы эти данные изменить (таковы особенности блокировок на уровне изоляции Read Committed). Поэтому управляемая блокировка необходима для того, чтобы гарантировать, что прочитанные данные не будут изменены до окончания нашей транзакции.

Каким образом управляемая блокировка препятствует изменению данных? В результате выполнения метода Заблокировать() в менеджере транзакционных блокировок появляются записи о тех данных, которые мы блокируем (естественно, если они не конфликтуют с существующими блокировками) (рис. 21).

clip_image020

Рис. 21. Установка управляемых блокировок

При любой попытке модификации данных информационной базы система автоматически будет пытаться установить исключительные управляемые блокировки для модифицируемых данных. Таким образом, если окажется, что другая транзакция пытается модифицировать те данные, которые мы уже заблокировали, менеджер транзакционных блокировок не даст ей установить нужные блокировки, т.к. исключительная блокировка, которую пытается установить другая транзакция, не совместима с нашей разделяемой блокировкой (рис. 22).

clip_image021

Рис. 22. Невозможно установить исключительную блокировку на номенклатуру 2

Значит система не сможет изменить данные, заблокированные нами до тех пор, пока наша транзакция не закончится и наша блокировка не будет снята автоматически при завершении транзакции (рис. 23).

clip_image022

Рис. 23. Исполнение кода продолжается после завершения нашей транзакции

Если бы мы использовали только разделяемую управляемую блокировку, то мы могли бы получить конфликт блокировок (deadlock) с другой транзакцией.

Например, наша и другая транзакция начали читать остатки из регистра Остатки номенклатуры. Списки номенклатуры, для которых читаются остатки в одной и другой транзакции, имеют одинаковые элементы. При этом система в нашей и в другой транзакции устанавливает разделяемую блокировку на читаемые данные. Две разделяемые блокировки на один и тот же ресурс («пересекающиеся» элементы номенклатуры) совместимы друг с другом (рис. 24).

clip_image023

Рис. 24. Разделяемые блокировки совместимы друг с другом

Затем мы закончили читать данные и хотим записать в этот регистр «новые остатки» для прочитанной номенклатуры. Мы не можем это сделать, т.к. для этого система должна установить исключительную блокировку на записываемые данные, но этому мешает разделяемая блокировка, установленная на часть этих данных другой транзакцией. Наша транзакция становится в очередь, ожидая снятия разделяемой блокировки, установленной другой транзакцией (рис. 25).

clip_image024

Рис. 25. Наша транзакция не может установить исключительную блокировку на номенклатуру 2

В это время другая транзакция также закончила чтение данных и хочет записать в этот регистр «новые остатки» для прочитанной номенклатуры. Она не может это сделать, т.к. для этого система должна установить исключительную блокировку на записываемые данные, но этому мешает разделяемая блокировка, установленная на часть этих данных нашей транзакцией. Другая транзакция становится в очередь, ожидая снятия разделяемой блокировки, установленной нашей транзакцией транзакцией (рис. 26).

clip_image025

Рис. 26. Конфликт блокировок: другая транзакция также не может установить блокировку на номенклатуру 2

В результате получается конфликт блокировок (deadlock), который может быть разрешен только принудительной отменой одной из транзакций.

Поэтому в данном случае необходима исключительная блокировка (рис. 27).

clip_image026

Рис. 27. Установка исключительных блокировок

В этом случае, когда другая транзакция, использующая управляемые блокировки, попытается начать чтение данных, которые мы заблокировали, она не сможет этого сделать. Менеджер тразакционных блокировок не даст ей установить никакую управляемую блокировку (ни разделяемую, ни исключительную) на наши данные, т.к. они не совместимы с нашей исключительной блокировкой (рис. 28).

clip_image027

Рис. 28. Другая транзакция не может установить блокировку на номенклатуру 2

В результате исполнение кода в другой транзакции будет остановлено и система будет ожидать снятия нашей исключительной блокировки. А наша транзакция сможет завершится, т.к. другая транзакция не имеет возможности заблокировать те записи, которые понадобятся нам для модификации (рис. 29).

clip_image028

Рис. 29. Наша транзакция успешно завершается

1