Имя: Пароль:
1C
1С v8
Управляемая блокировка периодич. регистра сведений.
0 f87
 
13.10.11
09:47
Блокируются все данные совпадающие по измерениям, без учета ПЕРИОДА.

А хочу заблокировать только первые 5 записей регистра.

Вот код...



Процедура ОбработатьЖурнал() Экспорт
Запрос = Новый Запрос();      
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 5
|      ЖурналВыгрузкиOptimum.Период КАК Период,
|      ЖурналВыгрузкиOptimum.Подключение,
|      ЖурналВыгрузкиOptimum.Подключение.СтрокаПодключения КАК СтрокаПодключения,
|      ЖурналВыгрузкиOptimum.ОбъектOptimum,
|      ЖурналВыгрузкиOptimum.ОбъектБД,
|      ЖурналВыгрузкиOptimum.Команды,
|      ЖурналВыгрузкиOptimum.Инкремент,
|      ЖурналВыгрузкиOptimum.СвободноеВыполнение
|ИЗ
|      РегистрСведений.ЖурналВыгрузкиOptimum КАК ЖурналВыгрузкиOptimum
|ГДЕ
|      ЖурналВыгрузкиOptimum.Инкремент < 3
|
|УПОРЯДОЧИТЬ ПО
|      Период";      

Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат;
КонецЕсли;      

НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый);        

Если Не ЗаблокироватьЗаписи(Результат) Тогда
ОтменитьТранзакцию();
Возврат;
КонецЕсли;      

Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Запись = РегистрыСведений.ЖурналВыгрузкиOptimum.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(Запись, Выборка, "Период, Подключение, ОбъектOptimum, ОбъектБД");

Запись.Прочитать();

СписокСОшибками = Новый СписокЗначений();
СписокСОшибками.ТипЗначения = Новый ОписаниеТипов("Строка");  

//Если f87_Optimum.ВыполнитьЗаписьЖурнала(Выборка, Запись.ОписаниеОшибки, СписокСОшибками) Тогда
//      Запись.Удалить();            
//Иначе
//      Если Выборка.СвободноеВыполнение Тогда
//            Запись.Команды = Новый ХранилищеЗначения(СписокСОшибками);            
//      КонецЕсли;
//      
//      Запись.Инкремент = Выборка.Инкремент + 1;
//      Запись.Записать(Истина);      
//КонецЕсли;        
КонецЦикла;  

ЗафиксироватьТранзакцию();  
КонецПроцедуры

Функция ЗаблокироватьЗаписи(РезультатЗапроса)
Блокировка = Новый БлокировкаДанных;

ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЖурналВыгрузкиOptimum");
ЭлементБлокировки.ИсточникДанных = РезультатЗапроса;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Период",                  "Период");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Подключение",            "Подключение");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("ОбъектOptimum",      "ОбъектOptimum");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("ОбъектБД",                  "ОбъектБД");

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

Попытка              
Блокировка.Заблокировать();              
Исключение
Возврат Ложь;      
КонецПопытки;

Возврат Истина;
КонецФункции

Спасибо
1 5 Элемент
 
13.10.11
10:07
База файловая?
2 Maxus43
 
13.10.11
10:11
общие модули аналогично Нику называть щас модно?) оставить след в истории?
3 Рыжий Лис
 
13.10.11
10:53
(0) А блокировка СУБД или 1С?
4 Maxus43
 
13.10.11
11:01
и это, какой режим блокировки стоит в конфигураторе у самой конфы и этих регистров?
5 f87
 
13.10.11
11:10
(1) - Обижаешь, SQL

(3) - не совсем понял вопрос, думаю 1С

(4)
Режим управления блокировкой (конф) - Управляемая
Режим управления блокировкой (Регистр) - Управляемая
Транзакция так же - Управляемая

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

Интересное наблюдение при отладке...

ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Период",                  "Период");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Подключение",            "Подключение");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("ОбъектOptimum",      "ОбъектOptimum");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("ОбъектБД",                  "ОбъектБД");
// ЭлементБлокировки.Поля - содержит все 4 поля

Блокировка.Заблокировать();
// ЭлементБлокировки.Поля ИЗЧЕЗАЕТ поле "Период"
6 Vovan1975
 
13.10.11
11:14
тупой вопрос - а чего не используете конструкцию "ДЛЯ ИЗМЕНЕНИЯ" ?
7 Господин ПЖ
 
13.10.11
11:17
(3) у него все управляемое.. так что 1с
8 Maxus43
 
13.10.11
11:21
а если не источник юзать?
ЭлементБлокировкиДанных (DataLockItem)
УстановитьЗначение (SetValue)
Для пространства РегистрСведений.<имя> - Период (если есть), <имя измерения>;
9 Vetal_978
 
13.10.11
11:28
как-то давно тоже пытался блокировку по периоду сделать - не получилось, но у меня вываливалась какая-то ошибка.

(6) Семен Семеныч...
10 f87
 
13.10.11
11:31
(8) Периодичность - В пределах секунды
Что ты хочешь сказать?
11 Maxus43
 
13.10.11
11:33
(10) я хочу сказать что попробуй использовать не "ИспользоватьИзИсточникаДанных" а устанавливай явно методом УстановитьЗначение
12 f87
 
13.10.11
11:34
(11) Ща попробую
13 f87
 
13.10.11
11:41
(11) Только вот не понятно
<БлокируемоеЗначение> - Тип Произвольный либо Диапазон
Так вот пять записей содержит разные измерения.

Значет блокировать по одной записи?
14 Maxus43
 
13.10.11
11:43
(13) имхо по периоду как раз заблокировать, все измерения... конкретно произвольные наборы записей блокирнуть хз
15 f87
 
13.10.11
12:01
Зделал так

Диапазон = Новый Диапазон(НачалоДня(Выборка.Период), КонецДня(Выборка.Период));  
ЭлементБлокировки.УстановитьЗначение("Период", Диапазон);


Но блокируется ВСЯ таблица. Что за хрень не знаю.
На период вообще не реагирует.

И ни каких ошибок!
16 f87
 
13.10.11
12:10
А главное если зделать

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

То, аналогично, полная тишина.
17 ProgAL
 
13.10.11
12:18
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЖурналВыгрузкиOptimum");

может быть надо
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЖурналВыгрузкиOptimum.НаборЗаписей");
18 f87
 
13.10.11
12:21
(17) Мой регистр не подчинен регистратору (Независимый)
19 Jolly Roger
 
13.10.11
13:18
(0) какой релиз платформы? сервер 32 или 64?
20 Sonny
 
13.10.11
13:25
Хорошо бы так же понять: каким образом автор узнал, что блокируются все записи по измерениям без учета периода?
21 f87
 
13.10.11
14:13
(20) Вопрос не потеме.
Создай свой сабж я тебе отвечу.
22 Sonny
 
13.10.11
14:25
(21) Кхм... Вообще-то это тебе нужно, а не мне. У меня всё работает нормально. Но если влом ответить, тогда в сад, помогать тебе желания уже нет.
23 МихаилМ
 
13.10.11
14:51
если первые 5 будут все на разных страницах

то блокировка может быть не страничная, а на всю таблицу.

это нормально,  если период не первое поле в кластерном индексе.
24 Господин ПЖ
 
13.10.11
15:02
(23) какие страницы/таблицы... в упр. режиме sql вообще не при делах...
25 Рыжий Лис
 
13.10.11
18:53
(23) Блокировки и в управляемом режиме могут быть как 1С, так и SQL. Если во время открытой транзакции прочитать из базы данных, запрос сформированный платформой будет без hint'а NOLOCK и прочитанные данные будут заблокированы SQL. Например если приведенный кусок кода вызывается из обработки проведения документа и поле Инкремент не индексировано и не первое в таблице или количество записей регистра невелико, план запроса будет использовать index scan или table scan. В результате все записи прошедшие через scan будут заблокированы SQL.
26 artik2
 
13.10.11
21:49
(25) и на какой период записи будут заблокированы?
27 Рыжий Лис
 
14.10.11
09:19
(26) До конца транзакции. Либо явной ЗавершитьТранзакцию, либо завершения проведения документа.
28 5 Элемент
 
14.10.11
09:20
(25) >> и прочитанные данные будут заблокированы SQL
иди учи мат часть
29 VVi3ard
 
14.10.11
10:25
(28) на самом деле (25) дело говорит.
30 VVi3ard
 
14.10.11
10:43
ТС приведи полностью сообщение о блокировке так же в консоли SQL можно посмотреть тип блокировки это тоже не помешало бы.
31 VVi3ard
 
14.10.11
10:46
(28) В мат части(ИТС) в статье Анализ и устранение взаимоблокировок описан случай который описал 25
32 5 Элемент
 
14.10.11
11:01
(29) как они блокируются?
33 f87
 
14.10.11
13:28
(30)
Когда данные заблокированны (остановка при отладке), то из другово клинента пытаюсь открыть запись вылетает:
"Конфликт блокировок при выполнении транзакции. Превышено максимальное время ожидания предоставления блокировки"

Где посмотреть тип блокировки - не нашел.
Вроде пишет везде разделяемая, а я в коде указал исключительную.
34 5 Элемент
 
14.10.11
16:59
(33) где у тебя стоит точка останова?
В твоем коде точно стоят комментарии на коде который изменяет записи?
35 Sonny
 
14.10.11
17:12
(34) Без паяльника не взлетит :)
36 5 Элемент
 
14.10.11
17:16
В общем есть предположение что у автора изменяются записи.
В этом случае SQL ставит блокировку. На что он поставит только ему известно: за прочтенные записи или на всю таблицу.

Точка останова стоит после изменения записей.

В этом случае будет срабатывать блокировка SQL, т.к. нельзя читать записи заблокированные при изменении.
37 Господин ПЖ
 
14.10.11
17:24
>Если во время открытой транзакции прочитать из базы данных, запрос сформированный платформой будет без hint'а NOLOCK и прочитанные данные будут заблокированы SQL

почему бы... там readcommited в управляемом... и опять же читать он их будет в shared без "ДЛЯ ИЗМЕНЕНИЯ", нах ему их блокировать?
38 f87
 
15.10.11
07:13
(34) Данные точно не меняются (за комментировал)

Остановка в конце процедуры "Возврат Истина;"

(36) "предположение что у автора изменяются записи."
я же код выложил, записи просто блокируются в транзакции, затем разблокируются

Спасибо за ваши мысли, много интересного.
Вот мои наблюдения.

Записи блокирутся моим кодом адекватно, все по измерениям. Укажу одно или же три измерения, меняю значения - блокировка ставится корректно. Бонально 1С не ставит блокировку по периоду. Может глюк какой-то?
8.2 (8.2.14.533)
Есть мысль зделать рег. не периодическим, и добавить ИЗМЕРЕНИЕ Период. Буду пробовать
39 f87
 
15.10.11
08:15
Ну в общем то все.
Убрал периодичность, создал измерение "Период1".

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

Вывод: 1С не ставит блокировку по стандартному реквизиту "Период"!

Есть мысли?
40 jump if zero
 
15.10.11
10:33
>>блокируются строго пять записей из запроса, даже при наличии совпадений по другим измерениям

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

и по периоду тоже работает.

и запрос у тебя выполняется вне управляемой транзакции , а значит может читать еще не закоммиченные данные и при таком условии
|ГДЕ
|      ЖурналВыгрузкиOptimum.Инкремент < 3

запросто возможно пересечение по измерениям сдругой транзакцией
41 f87
 
15.10.11
11:47
(40) Период естественно различный, интервал в секкунду/две

Запрос не блокирует данные, а лишь выбирает пять записей (вне транзакции, т.н. "Грязное чтение") которые я в дальнейшем ПОПРОБУЮ заблокировать.
И если будет пересечение с другой транзакцией то "Блокировка.Заблокировать();" выдаст исключение.
42 5 Элемент
 
15.10.11
12:23
(41) в транзакции не может быть грязного чтения
43 f87
 
18.10.11
07:06
(42) ???
>> (вне транзакции, т.н. "Грязное чтение")