исключение "грязного чтения" набора записей регистра сведений 1С #755007


#0 by МеталлКор
Добрый день, уважаемые коллеги. В системе на базе 8.2 предусмотрено два регл. задания: 1. Задание 1: помещает записи в регистр сведений, определенный рядом измерений (не подчинен регистратору, периодичность секунда), далее вторым шагом обрабатывает записи, заполняет некие реквизиты набора. При этом в начале и в конце обработки выставляется конструкции "НачатьТранзакцию", "ЗафисироватьТРанзакцию". Возможна ситуация, когда требуется отменить запись некоторого набора, в связи с чем применяется метод "ОтменитьТранзакицю". 2. Задание 2: должно обратиться к регистру сведений, отобрать записи по определенному фильтру и далее внести изменения в его набор записей. Вопрос: задание 2 должно получить для обработки набор записей тот, который окончательно обработан заданием 1 после выполнения команды "ЗафиксироватьТРанзакцию". На текущий момент в задание 2 попадают записи, которые добавлены заданием 1, но не обозначены как "ЗафиксироватьТРанзакцию". Как лучше организовать поведение системы с целью исключения "грязного" чтения заданием 2?
#1 by МеталлКор
Дополнительно: в свойствах конфигурации выставлен режим блокировки данных "Управляемый"
#2 by Сергиус
БлокировкаДанных в 1-м задании.
#3 by МеталлКор
Вот код: Выставлю точку остановы на последней строке. Если я делаю селект регл. задания 2, получаю результат, куда включены записи НаборЗаписей. а они попадать не должны.
#4 by Гёдза
чтение делать внутри транзакции
#5 by Гёдза
не заметил в коде транзакции. А без транзакции блокировка ничего не делает
#6 by МеталлКор
она есть, просто забыл указать. перед вызовом это процедуры идет "НачатьТранзакцию" из другого модуля. Аналогично после выполнения процедуры "ЗафиксироватьТранзакцию"
#7 by Cyberhawk
А ты в коде перед установкой блокировки проверь "ТранзакцияАктивна" и нам сообщи
#8 by Cyberhawk
И неясно, зачем вот это:
#9 by kihor
Согласен с . Чтение вне транзакции 1С - грязное. Если сделать НачатьТранзакцию в задании №2, а затем делать чтение, то будет другой, более высокий, уровень изоляции.
#10 by МеталлКор
так и есть, дает истину. сделал так: В регл. задании 2 сделал так: На выходе получил ошибку: Конфликт блокировок при выполнении транзакции: Microsoft OLE DB Provider for SQL Server: Превышено время ожидания запроса на блокировку. HRESULT=80040E31, SQLSrvr: SQLSTATE=HYT00, state=33, Severity=10, native=1222, line=1 Но меня интересует результат с пустым значением, то есть, обработка должна пройти и результат поиска должен дать 0
#11 by kihor
Время ожидания превышено, когда вы ставите точку останова в первом задании? Если у вас первая обработка ставит исключительную блокировку при попытке записать запись в регистр, то вторая обработка будет заблокирована при попытке прочитать эту запись, если не использовать грязное чтение. У вас это и происходит. Если первая обработка заканчивается быстро, то вторая обработка ждет окончания транзакции и продолжает чтение записи. Кстати, какой у вас режим работы 1С (файловый или клиент-серверный) и какая БД?
#12 by МеталлКор
мне необходимо, что бы второе задание отработало безаварийно и дало пустой результат, так как транзакция первого регл. задания не зафиксирована до конца. Это вообще реализуемо? У меня клиент-серверный вариант.
#13 by kihor
Если БД "блокировочник", как MSSQL, то не реализуемо, т.к. в MSSQL писатели блокируют читателей. В "версионниках" типа ORACLE - это реализуемо, т.к. там писатели не блокируют читателей. Но я не помню, как 1С себя ведет в случае ORACLE. Там по моему при автоматическом режиме блокируется вся таблица, но я не уверен. P.S. На всякий случай уточню, что я не утверждаю, что ORACLE лучше MSSQL. Просто они по разному подходят к этому вопросу.
#14 by ptiz
Должно работать Но что за метод "РазблокироватьДанные"? Не вижу такого в СП.
#15 by МеталлКор
это опечатка. данная команда не работает.
#16 by ptiz
"что бы второе задание отработало безаварийно и дало пустой результат" - а вот так уже не выйдет. Единственный способ - сначала записать пустой набор, потом его восстановить.
#17 by ptiz
При этом не использовать блокировки
#18 by Cyberhawk
Автор, попробуй во втором регл. задании не запросом, а созданием набора записей с установкой отбора и чтением проверить кол-во записей в получившемся наборе
#19 by Casey1984
Разнести рег задания по графику?
#20 by Casey1984
Придумать признак "МОЖНО ЧИТАТЬ"?
#21 by Casey1984
И да, я не спец в блокировках, разве нельзя увидеть заблокирован ли объект/набор записей?
#22 by Casey1984
Можно еще блокировать с отбором по измерению, разве нет? первое пишет с отбором "измерение = 1", второе читает с отбором "измерение = 2", потом меняемся.
#23 by Casey1984
Я все сказал. ;)
#24 by and2
вообще то в таких случаях задания объединяют в пул с последовательным выполнением.
#25 by Neo111
Чтобы дало пустой результат, делать примерно как сказано в , т.е. до начала первой транзакции ставить какой-то признак, после установки которого вторая транзакция эти данные уже не прочитает. Либо реализовывать с помощью блокировок, а чтобы уменьшить вероятность таймаута, разнести задания по времени.
#26 by Сторно абсурда
помести Запрос.Выполнить.Выбрать; второго задания в попытку исключение а так, + 1
#27 by Casey1984
Действительно, нафиг их разделять?
#28 by Serginio1
#29 by Гёдза
переходи на 8.3 без режима совместимости с 8.2 и упр блокировки
#30 by Neo111
Если речь про уровень изоляции Read Comitted Snapsot, то в этом случае ТС будет получать последнюю зафиксированную версию данных, а не пустой результат.
#31 by bootini
Добавь в регистр измерение, например "номер сообщения" или булево "Обработано" , первое задание обрабатывает записи с номером сообщения "1", после обработки записей изменяет номер сообщения на "2", второе задание обрабатывает записи только с номером сообщение "2".
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С