Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   Управляемые блокировки (http://forums.kuban.ru/f1040/upravlyaemye_blokirovki-6933246.html)

ktVladimir 16.06.2015 22:13

Управляемые блокировки
 
Есть РС который очень активно юзается. те постоянно туда что то пишется и читается. Соответственно частенько валится на блокировках

Родился в голове некий алгоритм, максимально разнести запись и чтение по разным регистрам. Прошу покритиковать/предложить свое.. итак
РС ХХХ
реквизит
ресурсы
различные счетчики
Создаем второй регистр ХХХ2 идентичный но с добавлением еще одного реквизита УИД

шаг 1 массовая запись. для того чтоб избежать очереди на записи добавлен реквизит уид те я генерирую уид, создаю исключительную блокировку по обоим полям и записываю набор. таким образом я предполагаю что никаких очередей при записи в РС не будет
шаг 2. Регламент пытается заблокировать записи в ХХХ2 по реквизиту. Как только удается получить блокировку считывает все данные в тз и разблокирует записи. далее я создаю блокировку в ХХХ2 но уже по 2 параметрам, реквизиту + список уидов из тз (таким образом я блокирую записи которые впоследствии удалю, но при этом не заблокирую РС для записи по шагу 1). делаю копию тз и сворачиваю счетчики по основному реквизиту. в транзакции переношу данные из тз в РС ХХХ и очищаю записи в РС ХХХ2

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

Reaper 16.06.2015 22:27

Зачем?
Правильное чтение не конфликтует с записью и не порождает блокировок.

qweqwe123123 16.06.2015 22:27

единственно понятое считаю правильным: делай больше одинаковых РСов и пиши в них разные порции. читай хоть со всех, хоть в один потом сливай, пофик. в идеале ещё не плохо бы разнести РСы на разные физические диски.

ktVladimir 16.06.2015 22:46

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

Чучундер 16.06.2015 23:01

1-Reaper > а подробнее для неграмотных?
.
например, есть некий список "заданий на выполнение".
часть этого списка заданий (пул) выдана "на исполнение", но еще не исполнена.
пул заданий выполнен на "выносном устройстве".
идет процесс сброса выполненных заданий в список.
требуется гарантировано получить список неисполненных заданий.
???

Reaper 17.06.2015 01:25

4-Чучундер > Я правильно понимаю, что тебя интересует не сброс выполненных, а получение новой порции заданий на мобильное устройство?

roma n 17.06.2015 09:18

(1) судя по описанию - у (0) пытаются читаться изменяемые (Х заблокированные) данные, при чём заблокированы они достаточно [b]длительное время[/b], чтоб очередь отвалилась по таймауту.
Отсюда к (0) вопрос: между установкой блокировки и окончанием транзакции нет тяжёлых алгоритмов? Там только собственно запись?

Reaper 17.06.2015 10:37

6-roma n > Ну и что? Запрос в режиме совместимости с 8.2 и более ранними из под X данные вынимает на раз. Не видел что ли как выглядят отчеты, когда движения в регистр уже попали, а итоги еще не пересчитались? В версии 8.3 используются данные версии, предшествующей наложению X блокировки.

roma n 17.06.2015 11:15

(7) далеко не факт что у (0) данные читаются [u]вне транзакции[/u].

roma n 17.06.2015 11:17

+(8) да и не факт что (0) валится на чтении :)

Reaper 17.06.2015 11:46

9-roma n > Вот мы и вернулись к осоновам:
Зачем?

roma n 17.06.2015 11:59

10-Reaper > согласен :)
Собственно, (6) - попытка поймать за хвост [em]возможную[/em] причину проблемы с другой стороны, задав чуть более конкретный вопрос "зачем блокировка висит так долго?"

ktVladimir 17.06.2015 16:56

Ну на записи валится не может (при записи стоит исключительная блокировка), точнее может но по таймауту. А валится в основном по дедлоку. Ну да ладно разделив регистры я в общем то получил что хотел. Оперативность снизилась, зато выросла стабильность, что для этой задачи важнее. Сейчас у еня другой вопрос нарисовался. Можно ли считать все записи, не заблокированные в данный момент. Сейчас ситуация следующая, когда идёт поток записи в рс ххх2, порой проходит долгое время, прежде чем получается считать данные. Можно ли писать в режиме разделяемых блокировок? Ведь по идее я точно знаю что эти данные не будут изменены. Они уникальны. Тогда считая их я могу их обработать и удалить. Или же как получить все не заблокированы записи

ktVladimir 17.06.2015 17:03

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

Reaper 17.06.2015 17:08

Упорствуешь в своем костыле? Успехов...

ktVladimir 17.06.2015 17:23

Дело скорее не в костылях, а в недостатке знаний. При проведении документа происходит множество движений. В частности кусок связанный со счетчиками. Там создаётся блокировка считывается набор. Увеличивается счётчик и происходит запись. Все. Теперь про чтение есть динамические журналы которые читают этот рс для вывода счетчиков. Есть дедлоки. Я прост не придумал как разрешить ситуацию, кроме как максимально развести чтение и запись.

Reaper 17.06.2015 17:29

15-ktVladimir > Взаимная блокировка накладывается только тогда, когда есть два процесса, блокирующие несколько ресурсов. Чтение в списке на форме нужно было очень постараться сделать так, чтобы оно вызвало именно взаимоблокировку а не увеличение времени ожидания на блокировках. Давай сюда код того, что у тебя в списке на форме происходит.

roma n 17.06.2015 17:56

Дедлоки? O_o
16-Reaper > взаимная блокировка может накладываться и при использовании одного ресурса. При повышении уровня изоляции.
[em]Чтение в списке на форме нужно было очень постараться сделать так, чтобы оно вызвало именно взаимоблокировку[/em] + 100500

roma n 17.06.2015 17:58

(15) [em]Там создаётся блокировка считывается набор. Увеличивается счётчик и происходит запись[/em]
Точно последовательность такая? Блокировка создаётся исключительная или разделяемая? Она устанавливается ПЕРЕД считыванием набора?

Reaper 17.06.2015 18:23

17-roma n > Ну это уже моя необъективность - посчитал таланты автора недостаточными для реализации взаимной блокировки на укрупнениях посредством вмешательства в списки на форме.

EarlyBird 17.06.2015 19:24

[quote=Reaper;39304548]для реализации взаимной блокировки на укрупнениях [/quote]
а можно как-то без карточных терминов, русским языком пояснить, о чём вообще речь в этом топике?

roma n 17.06.2015 19:56

(20) можно и по простому :)
Представь себя на месте менеджера блокировок, а я с Reaper'Ом (надеюсь он не будет в обиде?) будем параллельно выполняемыми транзакциями, для простоты работающими по одинаковому алгоритму
Диалог развивается примерно так:

Я
Эй, Ирли, дружище! Мне нужны вот эти данные. Дашь поюзать? только пока я с ними работаю никому не позволяй их менять!

Ирли
Ok (наложена разделяемая блокировка)

Reaper
О, но мне тоже нужны как раз эти данные! И тоже пока я их юзаю нельзя никому их менять! Ирли, сможешь организовать?

Ирли
Не вопрос, ты же не хочешь их менять, а roma n читать их никому не запрещал... Забирай (наложена вторая разделяемая блокировка)

Я
О! Я тут внезапно осознал, что данные нужно поменять. Ирли, давай мы это дело провернем по быстрому (прошу изменить уровень блокировки до исключительной)

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

Reaper
Ирли, тут такое дело... Оказывается те данные, которые я намедни прочитал надо поменять. Я ж никому не помешаю? (Прошу повысить уровень до исключительного)

Ирли
Вообще-то roma n строго настрого запретил их менять, покуда он их не отпустит...
<выхватывает пистолет, стреляет в одного из надоедливых персонажей, сдувает вьющийся дымок>
Нет человека,-нет проблемы! Кто там жив- меняй свои данные

roma n 17.06.2015 20:11

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

Чучундер 17.06.2015 20:20

5-Reaper > угу, чтобы на мобильное устройство не ушел пул данных, который ушел на другой терминал.

Reaper 17.06.2015 21:59

23-Чучундер > Я бы ввел в объект, хранящий пул заданий, поле, в котором сохранял бы территориальную единицу, которую обслуживают конкурирующие за задания устройства. Для кладовщиков - помещение на складе, которое обслуживается док-станцией на которой происходит выдача заданий. Для торговых представителей - регион работы. А при синхронизации устройства первым делом блокировал данные по всему диапазону конкуренции. И уже после этого читал пул, набирал из него задачи, отмечал их как ушедшие на устройство и заканчивал работу.

ktVladimir 18.06.2015 11:16

(18)
запись. в момент записи набора РС вызывается модуль заполнения счетчика
Набор = РС.ХХХ.СоздатьНаборЗаписей();
Для Каждого ЭлементГруппа Из пМассивГрупп Цикл
БД = Новый БлокировкаДанных;
СБ = БД.Добавить("РС.ХХХ");
СБ.УстановитьЗначение("Группа" , ЭлементГруппа);
СБ.УстановитьЗначение("Пользователь" , Пользователь);
СБ.Режим = РежимБлокировкиДанных.Исключительный;
БД.Заблокировать();
Набор.Отбор.Группа.Установить(ЭлементГруппа);
Набор.Отбор.Пользователь.Установить(Пользователь);
Набор.Прочитать();
ВНабореЕстьЗаписи = (Набор.Количество()>0);
Если НЕ ВНабореЕстьЗаписи Тогда
Если Общие > 0 ИЛИ Новые > 0 Тогда
Запись = Набор.Добавить();
Запись.Группа = ЭлементГруппа;
Запись.Пользователь = Пользователь;
Запись.ВсегоОбъектов = ?(Общие > 0, Общие, 0);
Запись.НовыхОбъектов = ?(Новые > 0, Новые, 0);
КонецЕсли;
Иначе
Для Каждого Запись Из Набор Цикл
Запись.ВсегоОбъектов = Запись.ВсегоОбъектов + Общие;
Запись.НовыхОбъектов = Запись.НовыхОбъектов + Новые;
КонецЦикла;
КонецЕсли;
Набор.Записать(ВНабореЕстьЗаписи);

это запись

ktVladimir 18.06.2015 11:18

Отсюда как при записи возникает дедлок я с трудом представляю... поэтому то и думаю на чтение...

ktVladimir 18.06.2015 11:22

чтение в динамическом списке
ВЫБРАТЬ
Поля
ИЗ
Справочник.ННН КАК ННН
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
ХХХ.Пользователь КАК Пользователь,
ХХХ.Группа КАК Группа,
ХХХ.ВсегоОбъектов КАК ВсегоОбъектов,
ХХХ.НовыхОбъектов КАК НовыхОбъектов
ИЗ
РегистрСведений.ХХХ КАК ХХХ
ГДЕ
ХХХ.Пользователь = &Пользователь) КАК Счетчики
ПО (Счетчики.Группа = ННН.Ссылка)
ГДЕ
(НЕ ННН.Ссылка = ЗНАЧЕНИЕ(Справочник.ННН.Служебная))
И (НЕ ННН.Ссылка = ЗНАЧЕНИЕ(Справочник.ННН.ИмеюОтношение))
И (НЕ ННН.ПометкаУдаления)
И ВЫБОР
КОГДА ННН.Предопределенный
ТОГДА ИСТИНА
КОГДА ННН.ДоступенВсем
ТОГДА ИСТИНА
ИНАЧЕ ННН.Пользователь = &Пользователь
КОНЕЦ

roma n 18.06.2015 11:48

(26) дедлок - это всегда параллельные транзакции.

Цикл.
Сначала блокируй ВЕСЬ диапазон изменяемых данных, потом меняй.
Первая транзакция в цикле блокирует пространство1, потом пространство2; параллельная пытается заблокировать их в обратном порядке. Дедлок.

Reaper 18.06.2015 11:51

25-ktVladimir > Сударь извольте исполнить 2 простых правила:
1. Обеспечить для всего алгоритма единственную точку блокирования, в которой разом будут заблокированы все данные, нужные алгоритму.
2. Обеспечить чтение данных одним запросом.

И ваши волосы станут чистыми и шелковистыми...

ktVladimir 18.06.2015 11:52

(28) спасибо. проверю

ktVladimir 18.06.2015 12:04

Всем огромное спасибо за помощь и добавление скилов в мою копилку знаний)

Чучундер 18.06.2015 21:25

24-Reaper > Устройства всегда в онлайне в базе.

qweqwe123123 18.06.2015 23:00

31-ktVladimir > это значит, что не так уж и много пишется?

Morrison 18.06.2015 23:34

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

Я что-то пропустил? :)

Morrison 18.06.2015 23:43

+(34) Совсем не смог осознать заглавие темы учитывая его содержание.

Morrison 18.06.2015 23:44

2(2) Зря смеешься, вот теперь мне стало понятно, как это все делается. Оказывается на Т1С советуют.

Morrison 19.06.2015 00:02

+(36) А у меня появились последователи. Следующие тем тупым поим стандартам. Это просто удивительно. В первый раз увидел, думал - показалось, видимо я тут что-то делал и не помню. А теперь вижу, что нет, не показалось, причем новый код так же пишут. А я ведь их не учил, они его случайно увидели в смежной системе и стали использовать мои идеи.

Хотя, сам уже отошел дальше некуда. Вижу запрос, знаю, где исправить, но какая-то просто непреодолимая сила заставляет меня писать код с двумя ссылками и обрабатывать результат запрос . Время приемлемое? Приемлемое. ОК.

Reaper 19.06.2015 00:25

32-Чучундер > Тогда проблема выеженного яйца не стоит. Пользователь тыкаует в задание, а система в этот момент должна наложить пессимистические объектную блокировку. Если удалось - открываем задачу и пользователь её делает. Не удалось - сообщаем, что задачу ухватил другой пользователь, обновляем список, и пусть выбирает следующую задачу.

Morrison 19.06.2015 04:24

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


Текущее время: 15:46. Часовой пояс GMT +3.