Имя: Пароль:
1C
1С v8
Для чего нужно свойство "БлокироватьДляИзменения " ?
0 ChAlex
 
27.11.12
18:05
Не догоняю для чего это свойство нужно?. По документации:Устанавливает режим, при котором в процессе записи набора будет установлена управляемая блокировка для всех комбинаций измерений в соответствии с записями набора записей. Но...!
1. Блокировка наступит после записи набора, до записи момента записи пофиг что и как установлено.
2. Но если набор записать даже без установки этого свойства на набор автоматически накладывается управляемая блокировка системой по записи.

Т.е.
Движения.ОстаткиНоменклатуры.БлокироватьДляИзменения=Истина;

....

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

Эквивалентно просто:

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

В чем смысл этого свойства?!
1 Господин ПЖ
 
27.11.12
18:07
дает скулю хинт shareforupdate
2 Господин ПЖ
 
27.11.12
18:10
http://msdn.microsoft.com/ru-ru/library/ms175519(v=sql.105).aspx

блокировка обновления
3 ChAlex
 
27.11.12
18:23
(1) - при чем здесь скуль?. Я про логику 1С. Покажите мне различие поведения 1С с установкой и без установки оного свойства.
4 ChAlex
 
27.11.12
18:25
+(1) - и какой тогда хинт дает 1С при записи набора? :)
5 Serginio1
 
27.11.12
18:26
Есть в программировании такое понятие как много читателей один писатель. Так вот это блокировка для чтения, гарантирующая, что во время транзакции с этими данными из других транзакций ничего не произойдет.
6 Господин ПЖ
 
27.11.12
18:26
(3) в 1с логика не всегда есть
7 GROOVY
 
27.11.12
18:28
(0) на набор - да. На остатки и обороты - нет.
8 ChAlex
 
27.11.12
18:43
(5) -  разжевываю проведенные мной тесты (по временным интервалам, естественно блокировки проводятся в разных документах):

Методика работы предлагаемая 1С:
Тест 1.
Движения.Номенклатура.БлокироватьДляИзменения=Истина;

// в данной точке никаких изменений, заблокировать данный в другой транзакции получится
(Для теста берем след. код
Блокировка= Новый Блокировка();
Элемент=Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры")
Элемент.УстановитьЗначение("Товар",Товар);
Блокировка.Блокировать())

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

// вот тут наступает блокировка, и данные уже не заблокировать в другой транзакции

Тест 2.

// Еще на было записи набора данных и естественно блокирвка в другой транзакции работает

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

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

Так сказать найдите разницу.


Что касается чтения данных - то данные читаются в 1С всегда независимо от блокировок (ну вернее  чуть сложнее с учетом работы SQL - на момент записи в таблицу блокируется а потом доступно)
9 ChAlex
 
27.11.12
18:46
(7) - сначала не дошла суть сказанного. Действительно чтение остатков не тестировал. Надо попробовать
10 Жан Пердежон
 
27.11.12
18:48
(8) в твоем случае разницы нет;
а вот если ты будешь контроль остатков делать после записи - разница появится
11 ChAlex
 
27.11.12
18:49
и в чем же она появится, если не секрет?
12 Serginio1
 
27.11.12
18:50
(8) Данные читаются так как на них хинт стоит NOLOCK. Если же ты будешь использовать в транзакции то будут ждать.
Ты кстати блокировке установи

Блокировка.Режим = РежимБлокировкиДанных.Исключительный
Исключительный или Разделяемый (Shared)
13 ChAlex
 
27.11.12
18:55
(12) - итак в 1-м документ без всяких БлокироватьДляИзменения запись набора

во втором: попытка чтения запросом


       Запрос=Новый Запрос("ВЫБРАТЬ
                           |    ОстаткиНоменклатурыОстатки.Партия,
                           |    ОстаткиНоменклатурыОстатки.КоличествоОстаток
                           |ИЗ
                           |    РегистрНакопления.ОстаткиНоменклатуры.Остатки(, Партия = &Партия) КАК ОстаткиНоменклатурыОстатки");
       Запрос.УстановитьПараметр("Партия",Товар1);
       Рез=Запрос.Выполнить().Выбрать();
       Рез.Следующий();

- результат запрос не выполняется, данные блокированы!

Итак вопрос открыт: что дает особенного данное свойство?
14 ChAlex
 
27.11.12
18:59
Другими словами: независимо от установки БлокироватьДляИзменения=Истина для набора, данные все равно блокируются в момент записи (причем Исключительно). Поэтому не догоняю смысл использования данного свойства. Можно просто в нужном месте записывать набор записей, при этом система все равно заблокирует данные и разницы в одном и другом случае просто не нахожу. Но ведь она должна бы быть?
15 Жан Пердежон
 
27.11.12
19:04
(14) не так:
Первая транзакция

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

Вторая транзакиция:
<твой запрос>

То есть без БлокировкаДанных
16 Serginio1
 
27.11.12
19:04
(0) В первом случае у тебя блокировка по умолчанию Исключительный, которая не даст ни читать другим блокировкам ни писать.
А вот во втором случае нужно смотреть тип блокировки.
17 ChAlex
 
27.11.12
19:09
(15) что не так? в первой транзакции просто запись без всяких установок БлокироватьДляИзменения : Движения.Номенклатура.Записать();

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

(16) Речь идет исключительно об управляемых блокировках.
18 ChAlex
 
27.11.12
19:11
Вопрос когда ж нужно использовать БлокироватьДляИзменения? То есть, тот случай, когда данные не блокируются просто при записи набора? Вот этого никак нащупать не могу?
19 GROOVY
 
27.11.12
19:11
У регистра установлена управляемая блокировка? Тестишь на скуле?
20 ChAlex
 
27.11.12
19:13
(19) - да, регистр накопления - управляемые блокировки, документ тоже, SQL
21 ChAlex
 
27.11.12
19:14
единственный момент для регистра не установлен разделение итогов. Сейчас попробую с установленным флагом
22 ChAlex
 
27.11.12
19:17
с разделением итогов то же самое
23 ChAlex
 
27.11.12
19:19
То бишь схема с установкой БлокироватьДляИзменения и без оной работает абсолютно одинаково (ну или я не нахожу различий). Так в чем же сакральный смысл в БлокироватьДляИзменения? :)
24 Жан Пердежон
 
27.11.12
19:20
(23) попробуй тогда

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

Вторая транзакиция:
Движения.Номенклатура.Записать();
25 GROOVY
 
27.11.12
19:21
Сдается мне у тебя что то с технологией тестирования. В противном случае ты бы увидел блокировку на чтение, как это описано в документации.
26 Жан Пердежон
 
27.11.12
19:29
в общем, если у тебя стоит разделение итогов, первая транзакция - реализация, с контролем остатков после записи,
а вторая - поступление,
то, если поступление пройдет между записью и контролем - контроль будет кривой;
27 ChAlex
 
27.11.12
19:32
(25) - так я и так вижу блокировку на чтение. Я так предполагаю, если не устанавливать режим БлокироватьДляИзменения то в этом случае должна быть мене жесткая блокировка (иначе зачем тогда это свойство), но с другой стороны ведь идет запись набора (тут по любому должна бы быть полная блокировка на данные). Не догадываюсь как 1С хотела с этим разрулить, но не в этом суть.

Технология тестирования простая - создаю документ и провожу (в регистр пишу расход по одному товару)  и просто набор зписываю (без БлокироватьДляИзменения), после этого делаю останов (до выхода из обработчика проведения) что бы во втором документе при проведении прочитать остатки по записанному товару в первом документе. (запросом, ну аналогично можно попробовать заблокировать набор). В результате получаю правильную блокировку данных. Такое же поведение я ожидаю при установке БлокироватьДляИзменения перед записью набора в первом документе. Но результат теста показывает одинаковое поведение.
28 ChAlex
 
27.11.12
20:00
(26) - вы близки к истине, только объяснения не совсем понятны.
В общем, разобрался с данной ситуацией. Итак резюме:
1. С точки зрения чтения данных и блокировки данных (именно "БЛОКИРОВКИ" как объекта 1С) - тут использование данного свойства не имеет смысла (что без его использования, что с его использованием поведение 1С одинаковое, а именно исключительная блокировка по всем комбинациям измерений).
2. Использование данного свойства имеет смысл только при "Разрешении разделении итогов" для регистра. И все, что оно делает, так это запрещает параллельную запись в регистр по комбинации измерений. Если не разрешено разделение итогов, то данное свойство так же не имеет смысла, ибо в этом случае система тоже блокирует одновременную запись, а вот при разделении итогов - тут запись пройдет, если не установить БлокироватьДляИзменения.

Вот и весь сакральный смысл этого свойства. :)

Спасибо всем, кто принял участие в дискуссии
29 Serginio1
 
28.11.12
10:38
(17) А блокировки Исключительный или Разделяемый это разве не управляемые блокировки?

По умолчанию изоляция блокировки Read Commited
Была бы изоляция Repeatable read не было бы проблем с повторным чтением
wiki:Уровень_изолированности_транзакций#Repeatable_read_.28.D0.BF.D0.BE.D0.B2.D1.82.D0.BE.D1.80.D1.8F.D0.B5.D0.BC.D0.BE.D1.81.D1.82.D1.8C_.D1.87.D1.82.D0.B5.D0.BD.D0.B8.D1.8F.29
поэтому и приходится накладывать блокировки Разделяемый
http://v8.1c.ru/overview/Term_000000642.htm
30 Жан Пердежон
 
28.11.12
10:46
(28) смысл - блокировать меньше данных на меньшее время; реализуется как раз с помощью разделения итогов, контроля остатков ближе к концу транзакции и сабжа.
31 ChAlex
 
28.11.12
12:16
(30) - не совсем так: разделение итогов и контроль ближе к концу транзакции как бы разные сущности и совсем разное назначение. Разделение итогов как раз позволяет только обойти блокировку наложенную на набор записей, чем достигается параллельная запись в регистр, тем самым обеспечивая большую параллельность вот и все. А БлокироватьДляИзменения - просто блокирует данную возможность (как бы на время отключая разделение итогов). Вот и все.
32 Serginio1
 
28.11.12
12:43
(31) Я так понимаю, что БлокироватьДляИзменения  все же исключительная блокировка.
Но суть получается такая, что если тебе после записи в регистр нужно обратиться к итогам до конца транзакции тебе нужно ее заблокировать. Разницы в для блокировок Исключительный или Разделяемый нет, так как изоляция Read Commited будет дожидаться окончания транзакции так как данные изменены. По идее блокироваться должны и записи в зависимости от свойства "Запись движения при проведении"например Записывать модифицированные будет блокировать только измененные.
33 ChAlex
 
28.11.12
20:01
(32) - нет не так. БлокироватьДляИзменения  вообще никаким боком к режиму блокировки не относится. При записи набора ВСЕГДА устанавливается блокировка на записываемые данные, и как результат их нельзя получить запросом или заблокировать в другой транзакции. Но есть только одно НО! В случае разделяемых итогов 1С позволит во время блокировки записать набор по тем же измерениям если не установлено БлокироватьДляИзменения. Вот и все! и причем тут глубокие дебри про Read Commited, а  Записывать модифицированные и с ними иже си вообще к теме блокировки не имеют никакого значения .
34 ВалераОшкин
 
28.11.12
20:03
(33) где-то читал, что в режиме автоблокировок БлокироватьДляИзменения игнорируется
35 ВалераОшкин
 
28.11.12
20:03
(34) пардон, в режиме управляемых блокировок
36 ChAlex
 
28.11.12
20:04
(35) - я ж и говорю - это относится не к блокировке, а к запрету параллельной записи в регистр в случае разделения итогов регистра
37 ChAlex
 
28.11.12
20:05
Больше за этим НИЧЕГО не стоит.
38 ВалераОшкин
 
28.11.12
20:07
(37) не, если в режиме автоблокировок запросишь регистр с БлокироватьДляИзменения, то другая запись в регистр станет.

Проверял и парился в свое время по этому поводу.
39 ChAlex
 
28.11.12
20:11
ну так БлокироватьДляИзменения относится ТОЛЬКО к управляемым блокировкам. И как-то этим пользоваться в автоматических блокировках мысль не посещала
40 Serginio1
 
29.11.12
11:03
(33) А при том, что изоляция Read Commited дает читать только неизмененные данные и ели данные изменены то ожидать окончания транзакции.
По уму БлокироватьДляИзменения  имеет смысл только до записи. После записи уже вступает в силу уровень изоляции Read Commited.
41 GANR
 
29.11.12
12:19
(0) Такой вид блокировки имеет смысл если производится вначале запись, а уже потом - контроль отрицательных остатков.
42 Жан Пердежон
 
29.11.12
12:57
(40) несешь пургу, уже всё выше расписали
43 Serginio1
 
29.11.12
12:58
(42) А поподробнее в чем пурга?
44 Serginio1
 
29.11.12
13:04
43+ Если и есть смысл использования то  только не для SQL.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.