1С:Предприятие 8.2 /
Разработчикам /
Реализация обработки данных
Использование транзакций при чтении данных
Использование чтения вне транзакции
1.1. Если чтение данных из информационной базы должно быть ответственным , следует производить такое чтение в транзакции с предварительной установкой управляемых блокировок. В общем случае, ответственным следует считать любое чтение, на основе результатов которого производятся какие-либо изменения в информационной базе или принимаются решения.
Например, ответственное чтение данных требуется в следующих случаях:
- Чтение данных при проведении, для последующего формирования движений;
- Чтение данных для последующей целостной передачи в другую систему, например в программы типа «Клиент банк »;
- Выполнение групповой обработки объектов *
* Примечание: перед модификацией ссылочных объектов, обычно, следует устанавливать на них пессимистичные объектные блокировки.
Неправильно:
// 1. Прочитать регистр сведений Запрос = Новый Запрос( "ВЫБРАТЬ РАЗРЕШЕННЫЕ | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок |ИЗ | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету |ГДЕ | ЗаметкиПоПредмету.Предмет = &Предмет"); Запрос.УстановитьПараметр("Предмет", ПредметЗаметок); Выборка = Запрос.Выполнить().Выбрать(); КоличествоЗаметок = 0; Если Выборка.Следующий() Тогда КоличествоЗаметок = Выборка.КоличествоЗаметок; КонецЕсли; // 2. Записать в регистр сведений НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок); НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Предмет = ПредметЗаметок; НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1; НаборЗаписей.Записать();
Правильно:
// 1. Начать транзакцию для пакета из двух операций чтения и записи регистра НачатьТранзакцию(); Попытка // 2. Установить исключительную блокировку на интересующий диапазон записей регистра, // для того чтобы гарантировать, что в момент записи количество заметок не изменилось с момента чтения в каком-либо другом сеансе. БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("РегистрСведений.ЗаметкиПоПредмету"); ЭлементБлокировкиДанных.УстановитьЗначение("Предмет", ПредметЗаметок); ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный; БлокировкаДанных.Заблокировать(); // 3. Прочитать регистр сведений Запрос = Новый Запрос( "ВЫБРАТЬ РАЗРЕШЕННЫЕ | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок |ИЗ | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету |ГДЕ | ЗаметкиПоПредмету.Предмет = &Предмет"); Запрос.УстановитьПараметр("Предмет", ПредметЗаметок); Выборка = Запрос.Выполнить().Выбрать(); КоличествоЗаметок = 0; Если Выборка.Следующий() Тогда КоличествоЗаметок = Выборка.КоличествоЗаметок; КонецЕсли; // 4. Записать в регистр сведений НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей(); НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок); НоваяЗапись = НаборЗаписей.Добавить(); НоваяЗапись.Предмет = ПредметЗаметок; НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1; НаборЗаписей.Записать(); ЗафиксироватьТранзакцию(); Исключение // 5. Если при установке блокировки возникла исключительная ситуация из-за того, что регистр уже заблокирован в другом сеансе (или по другим причинам), // отменить транзакцию и записать сведения об ошибке в журнал регистрации . ОтменитьТранзакцию(); ЗаписьЖурналаРегистрации(НСтр("ru = 'Заметки'"), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение; КонецПопытки;
В некоторых случаях, ответственное чтение не требуется в силу решаемой прикладной задачи, например:
- Получение данных динамическими списками;
- Поиск данных;
- Формирование большинства отчетов.
В некоторых случаях, ответственное чтение не требуется, так как конкурентная работа с данными маловероятна или полностью исключена, например:
- Обращение к условно постоянной информации. Например, чтение константы ВалютаРегламентированногоУчета или обращение к учетной политике;
- Действия, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы;
- Действия над данными, доступ к которым имеет только один пользователь , поэтому конкурентная работа с ними маловероятна или полностью исключена.
Например, персональные данные, хранящиеся в «разрезе» пользователей.
1.2. В большинстве случаев, при выполнении чтения в обработчиках событий связанных с модификацией данных, весь код обработчика выполняется в рамках системной транзакции, которая открыта платформой, и явно открывать новую транзакцию не требуется.
Например, в системной транзакции выполняются обработчики модулей объектов и соответствующие им подписки на события:
- ПередЗаписью;
- ПриЗаписи;
- ПередУдалением.
Подробнее – см. документацию к платформе 1С:Предприятие .
1.3. Если в транзакции производится ответственное чтение данных без их последующего изменения, необходимо установить разделяемую управляемую блокировку (до выполнения чтения). Если же прочитанные данные в дальнейшем модифицируются – следует использовать исключительную блокировку, в противном случае возможно возникновение взаимоблокировки.
Пример установки разделяемой блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):
// 1. Установить разделяемую блокировку для ответственного чтения нескольких связанных объектов Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("Справочник.Приказы"); ЭлементБлокировки.УстановитьЗначение("Ссылка", ПриказСсылка); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый; Блокировка.Заблокировать(); // 2. Прочитать первый объект - приказ ПриказОбъект = ПриказСсылка.ПолучитьОбъект(); // 3. Прочитать второй объект – пользователя (автора приказа) АвторПриказа = ПриказОбъект.Автор.ПолучитьОбъект();
Пример установки исключительной блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):
// 1. Установить исключительную блокировку для ответственного чтения объекта с целью его дальнейшего изменения Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("Справочник.Приказы"); ЭлементБлокировки.УстановитьЗначение("Ссылка", ПриказСсылка); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // Можно не указывать, т.к. по умолчанию Исключительный Блокировка.Заблокировать(); // 2. Получить объект для его дальнейшей модификации Объект = ПриказСсылка.ПолучитьОбъект(); // Выполнить блокировку объекта от изменения другими режимами или пользователями Объект.Заблокировать(); Объект.Реквизит = ... // 3. Записать измененный объект Объект.Записать();
Использование чтения вне транзакции
2.1. Не следует завязывать логику механизмов на эффект грязного чтения ( возможность чтения данных незафиксированных транзакций), т.к. его нет в версионных СУБД (PostgreSQL, Oracle database), а прикладные решения должны быть работоспособны на всех СУБД, поддерживаемых платформой. Например, если фоновое задание работает в транзакции, не следует пытаться отслеживать состояние этого задания по изменениям в информационной базе – это не будет работать на версионных СУБД.
2.2. В редких случаях, может быть принято решение о выполнении чтения вне транзакции. Например, из соображений повышения параллельности при многопользовательской работе. *
* Примечание: На СУБД MS SQL попытка чтения вне транзакции может завершится ошибкой "Could not continue scan with NOLOCK due to data movement". Обычно, при возникновении такой ошибки следует попытаться повторно выполнить чтение. При этом число попыток и способ обработки ошибки - отдельный предмет проектирования в каждом конкретном случае.
См. также
- Общие сведения об избыточных блокировках
- Обработка исключений при использовании транзакций
- Блокирующее чтение остатков в начале транзакции
Тренинг-семинар «Как получить работу бухгалтера»
Курсы бухгалтеров с трудоустройством
Курсы программирования 1С:Предприятие 8.2
Другие материалы по теме:
регистрсведений.заметкипопредмету, иначе, ссылка, предмет, записать, ошибки, приказ, регистр сведений, работа, обработки, буфер обмена, копировать, выполнить, отбор, обмен, добавить, использование, выбрать, объект, изменения, конфигурирование, установить, данные, регистр, справочник, действия
Материалы из раздела: 1С:Предприятие 8.2 / Разработчикам / Реализация обработки данных
Другие материалы по теме:
Источники данных для расчетов бюджетирования
Блокировка данных объекта для редактирования из кода
Нас находят: Новый БлокировкаДанных, чтение с блокировкой данных 1с, 1с конкурентная работа с данными, можно ли установить управляемую блокировку из обработки начатьТранзакцию, 1с 8 использование транзакций при загрузке справочника данных, 1с 8 запрос на чтение с учетом транзакции, выполнения запросов в транзакции 1с, 1с как отключить блокировку на чтение, 1с 8 2 работа с MS SQL и транзакции, тоанзакции на чтение данных
Мы на Facebook